<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\admin\model\scanwork\Config as ConfigModel;
use app\admin\model\yuncunchu\Config as CloudConfigModel;
use think\Db;
use think\Request;
use Exception;

class Userex extends Api
{
    protected $noNeedLogin = ['login', 'autoLogin', 'test', 'dbTest', 'uploadImage', 'bindExistingUser', 'createAndBindUser', 'getUnboundUsers', 'updateServiceNotificationStatus', 'getSimpleProcessList', 'getSimpleUserList', 'getUserGroups', 'getDailyWorkRecords', 'getDailyWorkStats', 'auditDailyWorkReport', 'clockIn', 'clockOut', 'getTodayAttendance', 'getAttendanceList', 'getAttendanceStatistics'];
    protected $noNeedRight = ['*'];

    /**
     * 重写初始化方法，支持Bearer token
     */
    protected function _initialize()
    {
        // 支持Bearer token格式
        $authorization = $this->request->header('Authorization');
        if ($authorization && strpos($authorization, 'Bearer ') === 0) {
            $token = substr($authorization, 7); // 去掉 'Bearer ' 前缀
            $this->request->server(['HTTP_TOKEN' => $token]);
        }
        
        // 调用父类初始化
        parent::_initialize();
    }

    /**
     * 测试接口
     */
    public function test()
    {
        try {
            // 检查数据库连接
            $result = [];
            
            // 记录错误信息
            error_log('test - starting database check');
            
            // 检查表是否存在
            $tables = ['scanwork_allocation', 'scanwork_report', 'scanwork_order', 'scanwork_model', 'scanwork_product', 'scanwork_process'];
            foreach ($tables as $table) {
                try {
                    $exists = Db::query("SHOW TABLES LIKE '{$table}'");
                    $result[$table] = !empty($exists);
                    error_log("test - table {$table}: " . ($result[$table] ? 'exists' : 'not exists'));
                } catch (Exception $e) {
                    error_log("test - error checking table {$table}: " . $e->getMessage());
                    $result[$table] = false;
                }
            }
            
            // 检查各表的数据量
            if ($result['scanwork_allocation']) {
                try {
                    $result['allocation_count'] = Db::name('scanwork_allocation')->count();
                    error_log("test - allocation_count: " . $result['allocation_count']);
                } catch (Exception $e) {
                    error_log("test - error counting allocations: " . $e->getMessage());
                    $result['allocation_count'] = 'error';
                }
            }
            if ($result['scanwork_report']) {
                try {
                    $result['report_count'] = Db::name('scanwork_report')->count();
                    error_log("test - report_count: " . $result['report_count']);
                } catch (Exception $e) {
                    error_log("test - error counting reports: " . $e->getMessage());
                    $result['report_count'] = 'error';
                }
            }
            if ($result['scanwork_order']) {
                try {
                    $result['order_count'] = Db::name('scanwork_order')->count();
                    error_log("test - order_count: " . $result['order_count']);
                } catch (Exception $e) {
                    error_log("test - error counting orders: " . $e->getMessage());
                    $result['order_count'] = 'error';
                }
            }
            
            // 检查当前登录用户
            try {
                if ($this->auth->isLogin()) {
                    $user = $this->auth->getUserinfo();
                    $result['current_user'] = $user;
                    error_log("test - current_user: " . json_encode($user));
                    
                    if ($result['scanwork_allocation']) {
                        try {
                            $result['user_allocations'] = Db::name('scanwork_allocation')->where('user_id', $user['id'])->count();
                            error_log("test - user_allocations: " . $result['user_allocations']);
                        } catch (Exception $e) {
                            error_log("test - error counting user allocations: " . $e->getMessage());
                            $result['user_allocations'] = 'error';
                        }
                    }
                } else {
                    $result['current_user'] = 'not_login';
                    error_log("test - user not logged in");
                }
            } catch (Exception $e) {
                error_log("test - error checking user: " . $e->getMessage());
                $result['current_user'] = 'error: ' . $e->getMessage();
            }
            
            error_log("test - final result: " . json_encode($result));
            $this->success('数据库检查完成', $result);
        } catch (Exception $e) {
            error_log("test - main error: " . $e->getMessage());
            $this->error('数据库检查失败：' . $e->getMessage());
        }
    }

    /**
     * 数据库连接测试
     */
    public function dbTest()
    {
        try {
            // 测试基本数据库连接
            $result = [];
            
            // 获取数据库配置
            $config = config('database');
            $result['database_config'] = [
                'hostname' => $config['hostname'],
                'database' => $config['database'],
                'username' => $config['username'],
                'hostport' => $config['hostport']
            ];
            
            // 测试简单查询
            $testQuery = Db::query("SELECT 1 as test");
            $result['simple_query'] = $testQuery;
            
            // 获取所有表
            $tables = Db::query("SHOW TABLES");
            $result['all_tables'] = $tables;
            
            // 检查scanwork相关表
            $scanworkTables = Db::query("SHOW TABLES LIKE 'scanwork_%'");
            $result['scanwork_tables'] = $scanworkTables;
            
            $this->success('数据库连接测试完成', $result);
        } catch (Exception $e) {
            $this->error('数据库连接测试失败：' . $e->getMessage());
        }
    }

    /**
     * 上传报工图片
     */
    public function uploadImage()
    {
        // 检查是否有用户信息（通过token）
        $user = null;
        if ($this->auth->isLogin()) {
            $user = $this->auth->getUserinfo();
        }
        $itemNo = $this->request->post('item_no', ''); // 产品编号
        $reportId = $this->request->post('report_id', 0); // 报工ID
        
        if (!empty($_FILES['file'])) {
            $file = $_FILES['file'];
            
            if ($file['error'] == 0) {
                $ext = pathinfo($file['name'], PATHINFO_EXTENSION);
                $allowExt = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'jfif'];
                if (!in_array(strtolower($ext), $allowExt)) {
                    $this->error('不支持的文件格式');
                }
                
                if ($file['size'] > 10 * 1024 * 1024) {
                    $this->error('文件大小不能超过10MB');
                }
                
                $filename = uniqid() . '_' . ($itemNo ?: 'report') . '.' . $ext;
                $dateDir = date('Y-m-d');
                $uploadDir = 'uploads/baogong/' . $dateDir . '/';
                
                if (!is_dir($uploadDir)) {
                    mkdir($uploadDir, 0755, true);
                }
                
                $filepath = $uploadDir . $filename;
                
                if (move_uploaded_file($file['tmp_name'], $filepath)) {
                    $imageUrl = '/uploads/baogong/' . $dateDir . '/' . $filename;
                    
                    // 上传到云存储（根据默认配置选择存储提供商）
                    error_log('=== 开始上传图片到云存储 ===');
                    error_log('文件名: ' . $filename);
                    error_log('本地路径: ' . $filepath);
                    $cloudUrl = $this->uploadToCloudStorage($filepath, $filename);
                    error_log('云存储上传结果：' . ($cloudUrl ?: '失败'));
                    error_log('=== 云存储上传结束 ===');
                    if ($cloudUrl) {
                        // 小程序无法访问服务器本地文件，使用云存储URL作为主要URL
                        $imageUrl = $cloudUrl;
                        error_log('图片已上传到云存储：' . $cloudUrl . '，本地备份：' . '/uploads/baogong/' . $dateDir . '/' . $filename);
                    } else {
                        error_log('云存储上传失败，使用本地URL：' . $imageUrl);
                        // 如果云存储上传失败，为本地URL添加域名前缀，让小程序可以访问
                        $imageUrl = ConfigModel::getSiteDomain() . $imageUrl;
                        error_log('添加域名前缀后的URL：' . $imageUrl);
                        error_log('云存储配置可能有问题，请检查配置信息');
                    }
                     
                    // 如果有报工ID，直接保存图片记录
                    if ($reportId > 0 && !empty($itemNo)) {
                        try {
                            $item = Db::name('scanwork_product_item')
                                ->where('item_no', $itemNo)
                                ->find();
                            
                            if ($item) {
                                Db::name('scanwork_item_report_image')->insert([
                                    'item_id' => $item['id'],
                                    'report_id' => $reportId,
                                    'image_url' => $imageUrl,
                                    'upload_user_id' => $user['id'],
                                    'createtime' => time()
                                ]);
                            }
                        } catch (\Exception $e) {
                            // 记录错误但不影响上传
                            error_log('保存图片记录失败: ' . $e->getMessage());
                        }
                    }
                    
                    $localUrl = '/uploads/baogong/' . $dateDir . '/' . $filename;
                    $this->success('上传成功', [
                        'url' => $imageUrl, // 主要URL（七牛云URL或带域名的本地URL）
                        'local_url' => $localUrl, // 本地备份路径
                        'cloud_url' => $cloudUrl ?: 'https://img1.images.023ent.net' . $localUrl, // 七牛云URL（如果上传失败则构造七牛云URL）
                        'backup_info' => $cloudUrl ? '本地文件已保留作为备份，同时已上传到七牛云' : '七牛云上传失败，使用本地文件作为备用',
                        'upload_status' => $cloudUrl ? 'success' : 'failed',
                        'qiniu_status' => $cloudUrl ? 'uploaded' : 'failed'
                    ]);
                } else {
                    $this->error('文件上传失败');
                }
            } else {
                $this->error('文件上传错误');
            }
        } else {
            $this->error('没有选择文件');
        }
    }

    /**
     * 小程序自动登录（兼容旧版本）
     */
    public function autoLogin()
    {
        $code = $this->request->post('code');
        if (!$code) {
            $this->error('缺少微信授权码');
        }

        // 微信小程序配置
        $appid = ConfigModel::getMiniappAppid();
        $secret = ConfigModel::getMiniappSecret();
        
        // 获取微信openid
        $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code";
        $result = file_get_contents($url);
        $data = json_decode($result, true);
        
        if (isset($data['errcode'])) {
            $this->error('微信授权失败：' . $data['errmsg']);
        }
        
        $openid = $data['openid'];
        $session_key = $data['session_key'];
        $unionid = $data['unionid'] ?? '';
        
        // 查找是否已有绑定微信的用户
        $user = Db::name('user')->where('wechat_openid', $openid)->find();
        
        if ($user) {
            // 已绑定，直接登录
            $token = \fast\Random::alnum(32);
            \app\common\library\Token::set($token, $user['id']);
            
            $this->success('登录成功', [
                'token' => $token,
                'user' => $user,
                'bind_status' => 'bound', // 已绑定
                'need_bind' => false
            ]);
        } else {
            // 未绑定，返回需要绑定的状态
            $this->success('需要绑定账号', [
                'openid' => $openid,
                'unionid' => $unionid,
                'session_key' => $session_key,
                'bind_status' => 'unbound', // 未绑定
                'need_bind' => true
            ]);
        }
    }

    /**
     * 绑定现有FastAdmin用户
     */
    public function bindExistingUser()
    {
        $openid = $this->request->post('openid');
        $username = $this->request->post('username');
        $password = $this->request->post('password');
        $userInfo = $this->request->post('userInfo', []);
        
        if (!$openid || !$username || !$password) {
            $this->error('参数不完整');
        }
        
        try {
            // 验证用户名和密码
            $user = Db::name('user')->where('username', $username)->find();
            if (!$user) {
                $this->error('用户名不存在');
            }
            
            // 验证密码
            if (md5(md5($password) . $user['salt']) !== $user['password']) {
                $this->error('密码错误');
            }
            
            // 检查该用户是否已绑定其他微信账号
            if (!empty($user['wechat_openid']) && $user['wechat_openid'] !== $openid) {
                $this->error('该账号已绑定其他微信账号');
            }
            
            // 检查该微信是否已绑定其他账号
            $existingBind = Db::name('user')->where('wechat_openid', $openid)->find();
            if ($existingBind && $existingBind['id'] !== $user['id']) {
                $this->error('该微信账号已绑定其他用户');
            }
            
            Db::startTrans();
            try {
                // 绑定微信账号
                $updateData = [
                    'wechat_openid' => $openid,
                    'wechat_unionid' => $this->request->post('unionid', ''),
                    'updatetime' => time()
                ];
                
                // 更新微信用户信息
                if (!empty($userInfo)) {
                    if (empty($user['nickname']) || $user['nickname'] === $user['username']) {
                        $updateData['nickname'] = $userInfo['nickName'] ?? $user['nickname'];
                    }
                    if (empty($user['avatar'])) {
                        $updateData['avatar'] = $userInfo['avatarUrl'] ?? $user['avatar'];
                    }
                }
                
                Db::name('user')->where('id', $user['id'])->update($updateData);
                
                // 重新获取用户信息
                $user = Db::name('user')->where('id', $user['id'])->find();
                
                // 生成token
                $token = \fast\Random::alnum(32);
                \app\common\library\Token::set($token, $user['id']);
                
                Db::commit();
                
                $this->success('绑定成功', [
                    'token' => $token,
                    'user' => $user,
                    'bind_status' => 'bound'
                ]);
                
            } catch (Exception $e) {
                Db::rollback();
                $this->error('绑定失败：' . $e->getMessage());
            }
            
        } catch (Exception $e) {
            $this->error('绑定失败：' . $e->getMessage());
        }
    }

    /**
     * 创建新用户并绑定
     */
    public function createAndBindUser()
    {
        $openid = $this->request->post('openid');
        $username = $this->request->post('username');
        $nickname = $this->request->post('nickname'); // 添加nickname参数
        $password = $this->request->post('password');
        $email = $this->request->post('email', '');
        $mobile = $this->request->post('mobile', '');
        $userInfo = $this->request->post('userInfo', []);
        
        if (!$openid || !$username || !$nickname || !$password) {
            $this->error('参数不完整');
        }
        
        try {
            // 验证用户名是否已存在
            $existingUser = Db::name('user')->where('username', $username)->find();
            if ($existingUser) {
                $this->error('用户名已存在');
            }
            
            // 验证邮箱是否已存在
            if (!empty($email)) {
                $existingEmail = Db::name('user')->where('email', $email)->find();
                if ($existingEmail) {
                    $this->error('邮箱已被使用');
                }
            }
            
            // 验证手机号是否已存在
            if (!empty($mobile)) {
                $existingMobile = Db::name('user')->where('mobile', $mobile)->find();
                if ($existingMobile) {
                    $this->error('手机号已被使用');
                }
            }
            
            // 检查该微信是否已绑定其他账号
            $existingBind = Db::name('user')->where('wechat_openid', $openid)->find();
            if ($existingBind) {
                $this->error('该微信账号已绑定其他用户');
            }
            
            Db::startTrans();
            try {
                // 生成密码盐
                $salt = \fast\Random::alnum();
                
                // 创建新用户
                $userData = [
                    'group_id' => 1, // 默认用户组
                    'username' => $username,
                    'nickname' => $nickname, // 直接使用传递的nickname
                    'password' => md5(md5($password) . $salt),
                    'salt' => $salt,
                    'email' => $email,
                    'mobile' => $mobile,
                    'avatar' => $userInfo['avatarUrl'] ?? '',
                    'wechat_openid' => $openid,
                    'wechat_unionid' => $this->request->post('unionid', ''),
                    'status' => 'normal',
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                $userId = Db::name('user')->insertGetId($userData);
                $user = Db::name('user')->where('id', $userId)->find();
                
                // 生成token
                $token = \fast\Random::alnum(32);
                \app\common\library\Token::set($token, $user['id']);
                
                Db::commit();
                
                $this->success('创建并绑定成功', [
                    'token' => $token,
                    'user' => $user,
                    'bind_status' => 'bound'
                ]);
                
            } catch (Exception $e) {
                Db::rollback();
                $this->error('创建失败：' . $e->getMessage());
            }
            
        } catch (Exception $e) {
            $this->error('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 获取未绑定的用户列表（用于绑定选择）
     */
    public function getUnboundUsers()
    {
        $keyword = $this->request->get('keyword', '');
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        
        $where = [['wechat_openid', '=', '']];
        
        if (!empty($keyword)) {
            $where[] = ['username|nickname|mobile|email', 'like', "%{$keyword}%"];
        }
        
        $list = Db::name('user')->where($where)
            ->field('id,username,nickname,mobile,email,createtime')
            ->order('id desc')
            ->paginate($limit, false, ['page' => $page]);
        
        $this->success('获取成功', [
            'list' => $list->items(),
            'total' => $list->total(),
            'page' => $page,
            'limit' => $limit
        ]);
    }

    /**
     * 解除微信绑定
     */
    public function unbindWechat()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录');
        }
        
        $user = $this->auth->getUserinfo();
        
        try {
            $updateData = [
                'wechat_openid' => '',
                'wechat_unionid' => '',
                'updatetime' => time()
            ];
            
            $result = Db::name('user')->where('id', $user['id'])->update($updateData);
            
            if ($result) {
                $this->success('解除绑定成功');
            } else {
                $this->error('解除绑定失败');
            }
            
        } catch (Exception $e) {
            $this->error('解除绑定失败：' . $e->getMessage());
        }
    }

    /**
     * 获取绑定状态
     */
    public function getBindStatus()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录');
        }
        
        $user = $this->auth->getUserinfo();
        
        $userInfo = Db::name('user')->where('id', $user['id'])->find();
        if (!$userInfo) {
            $this->error('用户不存在');
        }
        
        $this->success('获取成功', [
            'is_wechat_bound' => !empty($userInfo['wechat_openid']),
            'wechat_openid' => $userInfo['wechat_openid'],
            'wechat_unionid' => $userInfo['wechat_unionid']
        ]);
    }

    /**
     * 获取用户信息
     */
    public function getUserInfo()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        
        // 获取完整的用户信息（包含group_id）
        $fullUser = Db::name('user')->where('id', $user['id'])->find();
        if ($fullUser) {
            $user = array_merge($user, $fullUser);
        }
        
        // 获取用户组信息
        if (isset($user['group_id']) && $user['group_id'] > 0) {
            $group = Db::name('user_group')->where('id', $user['group_id'])->find();
            $user['group_name'] = $group ? $group['name'] : '';
        } else {
            $user['group_name'] = '';
        }
        
        // 调试信息
        error_log('getUserInfo - user: ' . json_encode($user));
        
        $this->success('获取成功', $user);
    }

    /**
     * 修改用户信息
     */
    public function updateUserInfo()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $username = $this->request->post('username');
        $nickname = $this->request->post('nickname');
        $email = $this->request->post('email');
        $mobile = $this->request->post('mobile');
        $password = $this->request->post('password');
        $group_id = $this->request->post('group_id');
        
        $updateData = [];
        
        if ($username) {
            // 检查用户名是否已经修改过（通过检查是否以wx_开头）
            $currentUser = Db::name('user')->where('id', $user['id'])->find();
            if ($currentUser && !str_starts_with($currentUser['username'], 'wx_')) {
                $this->error('用户名只能修改一次');
            }
            
            // 检查用户名是否已存在
            $exists = Db::name('user')->where('username', $username)->where('id', '<>', $user['id'])->find();
            if ($exists) {
                $this->error('用户名已存在');
            }
            $updateData['username'] = $username;
        }
        
        if ($nickname) {
            $updateData['nickname'] = $nickname;
        }
        
        if ($email) {
            // 验证邮箱格式
            if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $this->error('邮箱格式不正确');
            }
            // 检查邮箱是否已存在
            $exists = Db::name('user')->where('email', $email)->where('id', '<>', $user['id'])->find();
            if ($exists) {
                $this->error('邮箱已被使用');
            }
            $updateData['email'] = $email;
        }
        
        if ($mobile) {
            // 验证手机号格式
            if (!preg_match('/^1[3-9]\d{9}$/', $mobile)) {
                $this->error('手机号格式不正确');
            }
            // 检查手机号是否已存在
            $exists = Db::name('user')->where('mobile', $mobile)->where('id', '<>', $user['id'])->find();
            if ($exists) {
                $this->error('手机号已被使用');
            }
            $updateData['mobile'] = $mobile;
        }
        
        if ($password) {
            // 验证密码长度
            if (strlen($password) < 6) {
                $this->error('密码长度不能少于6位');
            }
            // 生成新的salt
            $salt = \fast\Random::alnum();
            $updateData['password'] = md5(md5($password) . $salt);
            $updateData['salt'] = $salt;
        }
        
        if ($group_id !== null && $group_id !== '') {
            // 验证用户组是否存在
            $group = Db::name('user_group')->where('id', $group_id)->where('status', 'normal')->find();
            if (!$group) {
                $this->error('选择的用户组不存在');
            }
            $updateData['group_id'] = intval($group_id);
        }
        
        if (empty($updateData)) {
            $this->error('没有要更新的数据');
        }
        
        $result = Db::name('user')->where('id', $user['id'])->update($updateData);
        
        if ($result) {
            $this->success('更新成功');
        } else {
            $this->error('更新失败');
        }
    }

    /**
     * 个人中心
     */
    public function profile()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        
        // 获取完整的用户信息
        $fullUser = Db::name('user')->where('id', $user['id'])->find();
        
        // 获取用户组信息
        if ($fullUser && isset($fullUser['group_id']) && $fullUser['group_id'] > 0) {
            $group = Db::name('user_group')->where('id', $fullUser['group_id'])->find();
            $fullUser['group_name'] = $group ? $group['name'] : '';
        } else {
            $fullUser['group_name'] = '';
        }
        
        // 格式化时间
        if ($fullUser) {
            $fullUser['jointime'] = $fullUser['jointime'] ? date('Y-m-d H:i:s', $fullUser['jointime']) : '';
            $fullUser['logintime'] = $fullUser['logintime'] ? date('Y-m-d H:i:s', $fullUser['logintime']) : '';
            $fullUser['createtime'] = $fullUser['createtime'] ? date('Y-m-d H:i:s', $fullUser['createtime']) : '';
        }
        
        // 获取统计数据
        $userId = $user['id'];
        $today = date('Y-m-d');
        $startTime = strtotime($today . ' 00:00:00');
        $endTime = strtotime($today . ' 23:59:59');
        
        // 今日任务数
        $todayTaskCount = Db::name('scanwork_allocation')
            ->where('user_id', $userId)
            ->where('createtime', 'between', [$startTime, $endTime])
            ->count();
        
        // 今日报工数（普通报工）
        $todayReportCount = Db::name('scanwork_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->where('createtime', 'between', [$startTime, $endTime])
            ->sum('quantity');
        
        // 今日主动报工数
        $todayActiveReportCount = Db::name('scanwork_active_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->where('createtime', 'between', [$startTime, $endTime])
            ->sum('quantity');
        
        // 今日工资（普通报工）
        $todayWage = Db::name('scanwork_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->where('createtime', 'between', [$startTime, $endTime])
            ->sum('wage');
        
        // 今日主动报工工资
        $todayActiveWage = Db::name('scanwork_active_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->where('createtime', 'between', [$startTime, $endTime])
            ->sum('total_wage');
        
        // 总统计数据
        $totalTasks = Db::name('scanwork_allocation')->where('user_id', $userId)->count();
        
        // 总报工数（普通报工数量 + 主动报工数量）
        $totalNormalReports = Db::name('scanwork_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->sum('quantity');
        $totalActiveReports = Db::name('scanwork_active_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->sum('quantity');
        
        // 总工资（普通报工工资 + 主动报工工资）
        $totalNormalWage = Db::name('scanwork_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->sum('wage');
        $totalActiveWage = Db::name('scanwork_active_report')
            ->where('user_id', $userId)
            ->where('status', 1)
            ->sum('total_wage');
        
        $this->success('获取成功', [
            'user' => $fullUser ?: $user,
            'today' => $today,
            'todayTaskCount' => $todayTaskCount,
            'todayReportCount' => ($todayReportCount ?: 0) + ($todayActiveReportCount ?: 0),
            'todayWage' => ($todayWage ?: 0) + ($todayActiveWage ?: 0),
            'totalTasks' => $totalTasks,
            'totalReports' => ($totalNormalReports ?: 0) + ($totalActiveReports ?: 0),
            'totalWage' => ($totalNormalWage ?: 0) + ($totalActiveWage ?: 0)
        ]);
    }

    /**
     * 获取任务列表
     */
    public function getTasks()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $workerId = $user['id'];
        
        $tasks = Db::name('scanwork_allocation')
            ->alias('a')
            ->join('scanwork_order o', 'a.order_id = o.id')
            ->join('scanwork_model m', 'a.model_id = m.id')
            ->join('scanwork_product p', 'm.product_id = p.id')
            ->join('scanwork_process pr', 'a.process_id = pr.id')
            ->where('a.user_id', $workerId)
            ->where('a.status', 0)
            ->field('a.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name')
            ->order('a.createtime desc')
            ->select();
        
        $this->success('获取成功', $tasks);
    }

    /**
     * 获取报工页面数据
     */
    public function getReportData()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $allocationId = $this->request->param('allocation_id') ?: $this->request->param('id');
        
        if (!$allocationId) {
            $this->error('未指定任务ID');
        }
        
        $allocation = Db::name('scanwork_allocation')
            ->alias('a')
            ->join('scanwork_order o', 'a.order_id = o.id')
            ->join('scanwork_model m', 'a.model_id = m.id')
            ->join('scanwork_product p', 'm.product_id = p.id')
            ->join('scanwork_process pr', 'a.process_id = pr.id')
            ->where('a.id', $allocationId)
            ->where('a.user_id', $user['id'])
            ->field('a.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name')
            ->find();
        
        if (!$allocation) {
            $this->error('任务不存在或不属于当前用户');
        }
        
        // 获取可报工的产品编号
        $productItems = Db::name('scanwork_product_item')
            ->where('allocation_id', $allocationId)
            ->where('status', 0) // 未报工状态
            ->order('item_no')
            ->select();
        
        // 计算已报数量和待报数量
        $reportedQuantity = Db::name('scanwork_report')
            ->where('allocation_id', $allocationId)
            ->where('status', 1)
            ->sum('quantity');
        
        $allocation['reported_quantity'] = intval($reportedQuantity);
        $allocation['remaining_quantity'] = max(0, $allocation['quantity'] - $allocation['reported_quantity']);
        $allocation['product_items'] = $productItems;
        
        $this->success('获取成功', $allocation);
    }

    /**
     * 提交报工
     */
    public function submitReport()
    {
        error_log("=== 小程序报工开始 ===");
        
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $workerId = $user['id'];
        
        error_log("小程序报工 - 用户ID: " . $workerId);
        
        // 获取参数
        $allocationId = intval($this->request->post('allocation_id', 0));
        $itemNos = $this->request->post('item_nos/a', []); // 产品编号数组，使用/a确保是数组
        $workType = $this->request->post('work_type', 'piece');
        $workHours = floatval($this->request->post('work_hours', 0));
        $remark = $this->request->post('remark', '');
        $imageUrls = $this->request->post('image_urls/a', []); // 图片URL数组，使用/a确保是数组
        
        error_log("小程序报工 - 参数: allocation_id=$allocationId, item_nos=" . json_encode($itemNos) . ", work_type=$workType, work_hours=$workHours");
        error_log("小程序报工 - remark: " . $remark);
        error_log("小程序报工 - image_urls类型: " . gettype($imageUrls));
        error_log("小程序报工 - image_urls内容: " . json_encode($imageUrls));
        
        // 确保image_urls是数组
        if (!is_array($imageUrls)) {
            if (is_string($imageUrls)) {
                $decoded = json_decode($imageUrls, true);
                if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                    $imageUrls = $decoded;
                } else {
                    $imageUrls = [];
                }
            } else {
                $imageUrls = [];
            }
        }
        
        error_log("小程序报工 - 处理后的图片数量: " . count($imageUrls));
        
        // 验证参数
        if (empty($allocationId)) {
            $this->error('分工ID不能为空');
        }
        
        if ($workType == 'piece' && empty($itemNos)) {
            $this->error('产品编号不能为空');
        }
        
        if ($workType == 'time' && empty($workHours)) {
            $this->error('工时不能为空');
        }
        
        try {
            // 验证分工是否存在且属于当前用户
            $allocation = Db::name('scanwork_allocation')->where('id', $allocationId)->find();
            if (!$allocation) {
                $this->error('分工不存在');
            }
            
            if ($allocation['user_id'] != $workerId) {
                $this->error('无权操作此分工');
            }
            
            error_log("小程序报工 - 分工验证通过");
            
            // 如果是计件工作，验证产品编号
            if ($workType == 'piece') {
                foreach ($itemNos as $itemNo) {
                    $item = Db::name('scanwork_product_item')
                        ->where('allocation_id', $allocationId)
                        ->where('item_no', $itemNo)
                        ->find();
                    
                    if (!$item) {
                        $this->error('产品编号不存在: ' . $itemNo);
                    }
                    
                    if ($item['status'] != 0) {
                        $this->error('该产品编号已报工: ' . $itemNo);
                    }
                }
                
                error_log("小程序报工 - 产品编号验证通过");
            }
            
            Db::startTrans();
            
            try {
                // 查找对应的小工单
                $workorder = Db::name('scanwork_workorder')->where([
                    'allocation_id' => $allocationId,
                    'user_id' => $workerId
                ])->find();
                
                // 创建报工记录
                $reportData = [
                    'allocation_id' => $allocationId,
                    'user_id' => $workerId,
                    'type' => $workType,
                    'quantity' => $workType == 'piece' ? count($itemNos) : $workHours,
                    'item_nos' => $workType == 'piece' ? json_encode($itemNos) : '',
                    'work_hours' => $workType == 'time' ? $workHours : null,
                    'remark' => $remark,
                    'status' => 0,
                    'wage' => 0,
                    'report_time' => time(),
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                // 如果找到小工单，关联小工单ID
                if ($workorder) {
                    $reportData['workorder_id'] = $workorder['id'];
                    error_log("小程序报工 - 找到小工单，ID: " . $workorder['id']);
                } else {
                    error_log("小程序报工 - 未找到对应的小工单");
                }
                
                $reportId = Db::name('scanwork_report')->insertGetId($reportData);
                error_log("小程序报工 - 报工记录创建成功，ID: " . $reportId);
                
                // 如果是计件工作，更新产品编号状态
                if ($workType == 'piece') {
                    foreach ($itemNos as $itemNo) {
                        Db::name('scanwork_product_item')
                            ->where('allocation_id', $allocationId)
                            ->where('item_no', $itemNo)
                            ->update([
                                'status' => 1,
                                'report_id' => $reportId,
                                'updatetime' => time()
                            ]);
                    }
                    
                    error_log("小程序报工 - 产品编号状态更新成功");
                    
                    // 保存图片
                    if (!empty($imageUrls) && is_array($imageUrls)) {
                        // 转换本地图片为七牛云URL
                        $cloudImageUrls = $this->convertLocalImagesToCloud($imageUrls);
                        
                        foreach ($cloudImageUrls as $imageUrl) {
                            try {
                                // 使用原生SQL避免ThinkPHP Db类的问题
                                $sql = "INSERT INTO fa_scanwork_item_report_image (item_id, report_id, image_url, upload_user_id, createtime) VALUES (?, ?, ?, ?, ?)";
                                $stmt = Db::getPdo()->prepare($sql);
                                
                                // 获取第一个产品编号的item_id
                                $firstItem = Db::name('scanwork_product_item')
                                    ->where('allocation_id', $allocationId)
                                    ->where('item_no', $itemNos[0])
                                    ->find();
                                
                                if ($firstItem) {
                                    $result = $stmt->execute([
                                        $firstItem['id'],
                                        $reportId,
                                        $imageUrl,
                                        $workerId,
                                        time()
                                    ]);
                                    
                                    if ($result) {
                                        error_log("小程序报工 - 图片记录保存成功: " . $imageUrl);
                                    } else {
                                        error_log("小程序报工 - 图片记录保存失败: " . $imageUrl);
                                    }
                                }
                            } catch (\Exception $e) {
                                error_log("小程序报工 - 图片保存失败: " . $e->getMessage());
                                // 不抛出异常，继续执行
                            }
                        }
                        error_log("小程序报工 - 图片保存完成，数量: " . count($cloudImageUrls));
                    }
                }
                
                // 更新分工的已报数量
                Db::name('scanwork_allocation')
                    ->where('id', $allocationId)
                    ->setInc('reported_quantity', $workType == 'piece' ? count($itemNos) : $workHours);
                
                // 更新小工单的报工数量
                if ($workorder) {
                    Db::name('scanwork_workorder')
                        ->where('id', $workorder['id'])
                        ->setInc('reported_quantity', $workType == 'piece' ? count($itemNos) : $workHours);
                    error_log("小程序报工 - 小工单报工数量更新成功");
                }
                
                Db::commit();
                error_log("小程序报工 - 提交成功");
                error_log("小程序报工 - 准备返回成功响应");
                
                $response = [
                    'report_id' => $reportId,
                    'item_no' => $itemNos[0] // 返回第一个产品编号，与工作的小程序保持一致
                ];
                
                error_log("小程序报工 - 响应数据: " . json_encode($response));
                
                // 直接返回，不使用success方法
                $result = [
                    'code' => 1,
                    'msg' => '报工成功',
                    'time' => time(),
                    'data' => $response
                ];
                
                error_log("小程序报工 - 最终响应: " . json_encode($result));
                return json($result);
                
            } catch (\Exception $e) {
                Db::rollback();
                error_log("小程序报工失败 - 数据库异常: " . $e->getMessage());
                $this->error('报工失败：' . $e->getMessage());
            }
            
        } catch (\Exception $e) {
            error_log("小程序报工失败 - 验证异常: " . $e->getMessage());
            $this->error('报工失败：' . $e->getMessage());
        }
    }

    /**
     * 扫码报工
     */
    public function scanReport()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $workerId = $this->auth->id;
        $qrCode = $this->request->post('qr_code');
        
        if (!$qrCode) {
            $this->error('二维码数据不能为空');
        }
        
        // 解析二维码数据（格式：allocation_id）
        $allocationId = $qrCode;
        
        // 验证分配记录
        $allocation = Db::name('scanwork_allocation')
            ->alias('a')
            ->join('scanwork_order o', 'a.order_id = o.id')
            ->join('scanwork_model m', 'a.model_id = m.id')
            ->join('scanwork_product p', 'm.product_id = p.id')
            ->join('scanwork_process pr', 'a.process_id = pr.id')
            ->where('a.id', $allocationId)
            ->where('a.user_id', $workerId)
            ->where('a.status', 0)
            ->field('a.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name')
            ->find();
        
        if (!$allocation) {
            $this->error('无效的二维码或任务已完成');
        }
        
        // 计算剩余数量
        $reportedQuantity = Db::name('scanwork_report')
            ->where('allocation_id', $allocationId)
            ->where('status', 1)
            ->sum('quantity');
        
        $remainingQuantity = max(0, $allocation['quantity'] - $reportedQuantity);
        
        if ($remainingQuantity <= 0) {
            $this->error('该任务已无待报数量');
        }
        
        $allocation['remaining_quantity'] = $remainingQuantity;
        $this->success('扫码成功', $allocation);
    }

    /**
     * 获取用户组列表
     */
    public function getUserGroups()
    {
        // 直接返回测试数据，不进行任何数据库操作
        error_log('getUserGroups - API被调用');
        
        $testGroups = [
            ['id' => 1, 'name' => '扪皮组'],
            ['id' => 2, 'name' => '木工组'],
            ['id' => 3, 'name' => '打底组'],
            ['id' => 4, 'name' => '缝纫组'],
            ['id' => 5, 'name' => '包装组']
        ];
        
        error_log('getUserGroups - 返回测试数据: ' . json_encode($testGroups));
        
        $this->success('获取成功', $testGroups);
    }

    /**
     * 生成唯一的产品编号
     */
    public function generateItemNos()
    {
        error_log('generateItemNos - 开始处理请求');
        error_log('generateItemNos - POST数据: ' . json_encode($this->request->post()));
        
        if (!$this->auth->isLogin()) {
            error_log('generateItemNos - 未登录');
            $this->error('未登录', null, 401);
        }
        
        error_log('generateItemNos - 登录验证通过');
        
        $order_id = $this->request->post('order_id');
        $model_id = $this->request->post('model_id');
        $process_id = $this->request->post('process_id');
        $quantity = intval($this->request->post('quantity'));
        
        error_log('generateItemNos - 参数: order_id=' . $order_id . ', model_id=' . $model_id . ', process_id=' . $process_id . ', quantity=' . $quantity);
        
        if (!$order_id || !$model_id || !$process_id || !$quantity) {
            error_log('generateItemNos - 参数错误');
            $this->error('参数错误');
        }
        
        try {
            error_log('generateItemNos - 开始查询订单、产品、工序信息');
            
            // 获取订单、产品、工序信息
            $order = Db::name('scanwork_order')->where('id', $order_id)->find();
            error_log('generateItemNos - 订单查询结果: ' . json_encode($order));
            
            $model = Db::name('scanwork_model')->where('id', $model_id)->find();
            error_log('generateItemNos - 型号查询结果: ' . json_encode($model));
            
            $process = Db::name('scanwork_process')->where('id', $process_id)->find();
            error_log('generateItemNos - 工序查询结果: ' . json_encode($process));
            
            if (!$order || !$model || !$process) {
                error_log('generateItemNos - 订单、产品型号或工序不存在');
                $this->error('订单、产品型号或工序不存在');
            }
            
            // 生成编号前缀：订单号-产品型号-工序
            $prefix = $order['order_no'] . '-' . $model['name'] . '-' . $process['name'] . '-';
            
            // 检查同一个订单、同一个产品型号、同一个工序内的编号唯一性
            error_log('generateItemNos - 开始查询已存在的编号');
            $existingNos = Db::name('scanwork_product_item')
                ->alias('pi')
                ->join('scanwork_allocation a', 'pi.allocation_id = a.id')
                ->where('a.order_id', $order_id)
                ->where('a.model_id', $model_id)
                ->where('a.process_id', $process_id)
                ->column('pi.item_no');
            error_log('generateItemNos - 已存在的编号: ' . json_encode($existingNos));
            
            // 同时检查主动报工中已使用的编号
            error_log('generateItemNos - 开始查询主动报工中已使用的编号');
            $activeReportNos = Db::name('scanwork_active_report_product_item')
                ->alias('arpi')
                ->join('scanwork_active_report ar', 'arpi.active_report_id = ar.id')
                ->where('ar.order_id', $order_id)
                ->where('ar.model_id', $model_id)
                ->where('ar.process_id', $process_id)
                ->column('arpi.item_no');
            error_log('generateItemNos - 主动报工中已使用的编号: ' . json_encode($activeReportNos));
            
            // 合并已存在的编号
            $allExistingNos = array_merge($existingNos, $activeReportNos);
            
            $itemNos = [];
            $currentNumber = 1;
            $generatedCount = 0;
            
            while ($generatedCount < $quantity) {
                $itemNo = $prefix . str_pad($currentNumber, 4, '0', STR_PAD_LEFT);
                
                // 如果编号在同一个订单、产品、工序内已存在，继续查找下一个可用编号
                if (!in_array($itemNo, $allExistingNos)) {
                    $itemNos[] = $itemNo;
                    $generatedCount++;
                }
                
                $currentNumber++;
            }
            
            error_log('generateItemNos - 生成成功，编号数量: ' . count($itemNos));
            error_log('generateItemNos - 生成的编号: ' . json_encode($itemNos));
            $this->success('生成成功', $itemNos);
            
        } catch (\Exception $e) {
            error_log('generateItemNos - 异常: ' . $e->getMessage());
            error_log('generateItemNos - 异常堆栈: ' . $e->getTraceAsString());
            $this->error('生成失败：' . $e->getMessage());
        }
    }

    /**
     * 重新上传报工图片（审核拒绝后）
     */
    public function reuploadReportImage()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $report_id = $this->request->post('report_id');
        $item_no = $this->request->post('item_no');
        
        if (!$report_id || !$item_no) {
            $this->error('参数错误');
        }
        
        // 检查报工记录是否存在且状态为拒绝
        $report = Db::name('scanwork_report')
            ->where('id', $report_id)
            ->find();
            
        if (!$report) {
            $this->error('报工记录不存在');
        }
        
        if ($report['status'] != 2) {
            $this->error('只有审核拒绝的报工记录才能重新上传');
        }
        
        // 检查产品编号是否存在
        $productItem = Db::name('scanwork_product_item')
            ->where('item_no', $item_no)
            ->where('report_id', $report_id)
            ->find();
            
        if (!$productItem) {
            $this->error('产品编号不存在');
        }
        
        // 处理文件上传
        $file = $this->request->file('image');
        if (!$file) {
            $this->error('请选择图片文件');
        }
        
        if (!$file->isValid()) {
            $this->error('文件上传失败：' . $file->getError());
        }
        
        try {
            // 先保存到本地
            $info = $file->validate(['size' => 10240 * 1024, 'ext' => 'jpg,jpeg,png,gif'])
                ->move('uploads/report/');
                
            if (!$info) {
                $this->error('文件保存失败：' . $file->getError());
            }
            
            $filename = $info->getSaveName();
            $url = request()->domain() . '/uploads/report/' . $filename;
            
            // 删除该产品编号的旧图片记录
            $oldImages = Db::name('scanwork_item_report_image')
                ->where('item_id', $productItem['id'])
                ->where('report_id', $report_id)
                ->select();
                
            foreach ($oldImages as $oldImage) {
                // 删除物理文件
                $filePath = ROOT_PATH . 'public' . $oldImage['image_url'];
                if (file_exists($filePath)) {
                    unlink($filePath);
                }
            }
            
            // 删除数据库记录
            Db::name('scanwork_item_report_image')
                ->where('item_id', $productItem['id'])
                ->where('report_id', $report_id)
                ->delete();
            
            // 保存新的图片记录
            $data = [
                'item_id' => $productItem['id'],
                'report_id' => $report_id,
                'image_url' => $url,
                'upload_user_id' => $this->auth->id ?? 0,
                'createtime' => time()
            ];
            
            $result = Db::name('scanwork_item_report_image')->insert($data);
            
            if ($result) {
                // 更新报工记录状态为待审核
                Db::name('scanwork_report')
                    ->where('id', $report_id)
                    ->update([
                        'status' => 0, // 待审核
                        'audit_reason' => '', // 清空拒绝原因
                        'audit_time' => null, // 清空审核时间
                        'updatetime' => time()
                    ]);
                
                $this->success('上传成功', ['url' => $url]);
            } else {
                $this->error('保存失败');
            }
            
        } catch (\Exception $e) {
            $this->error('上传失败：' . $e->getMessage());
        }
    }

    /**
     * 获取报工记录
     */
    public function getRecords()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        
        // 获取普通报工记录
        $normalRecords = Db::name('scanwork_report')
            ->where('user_id', $user['id'])
            ->where('status', '>', 0) // 只获取有效的记录
            ->order('createtime desc')
            ->select();
        
        // 为普通报工记录补充详细信息
        foreach ($normalRecords as &$record) {
            $allocation = Db::name('scanwork_allocation')->where('id', $record['allocation_id'])->find();
            
            if ($allocation) {
                $order = Db::name('scanwork_order')->where('id', $allocation['order_id'])->find();
                $record['order_no'] = $order ? $order['order_no'] : '';
                
                $model = Db::name('scanwork_model')->where('id', $allocation['model_id'])->find();
                $record['model_name'] = $model ? $model['name'] : '';
                
                if ($model) {
                    $product = Db::name('scanwork_product')->where('id', $model['product_id'])->find();
                    $record['product_name'] = $product ? $product['name'] : '';
                } else {
                    $record['product_name'] = '';
                }
                
                $process = Db::name('scanwork_process')->where('id', $allocation['process_id'])->find();
                $record['process_name'] = $process ? $process['name'] : '';
            } else {
                $record['order_no'] = '';
                $record['model_name'] = '';
                $record['product_name'] = '';
                $record['process_name'] = '';
            }
            
            // 从图片表获取报工图片
            $reportImages = Db::name('scanwork_report_image')
                ->where('report_id', $record['id'])
                ->select();
            
            $images = [];
            foreach ($reportImages as $img) {
                if (strpos($img['image_url'], 'http') !== 0) {
                    $img['image_url'] = request()->domain() . $img['image_url'];
                }
                $images[] = $img['image_url'];
            }
            $record['images'] = $images;
            
            // 获取产品编号信息（从scanwork_product_item表获取）
            $productItems = [];
            $productItemRecords = Db::name('scanwork_product_item')
                ->where('report_id', $record['id'])
                ->select();
            
            if (!empty($productItemRecords)) {
                foreach ($productItemRecords as $itemRecord) {
                    // 获取该产品编号的报工图片
                    $itemImages = Db::name('scanwork_item_report_image')
                        ->where('item_id', $itemRecord['id'])
                        ->where('report_id', $record['id'])
                        ->select();
                    
                    $itemImageUrls = [];
                    foreach ($itemImages as $img) {
                        if (!empty($img['image_url'])) {
                            if (strpos($img['image_url'], 'http') !== 0) {
                                $img['image_url'] = request()->domain() . $img['image_url'];
                            }
                            $itemImageUrls[] = $img['image_url'];
                        }
                    }
                    
                    $productItems[] = [
                        'item_no' => $itemRecord['item_no'],
                        'images' => $itemImageUrls, // 该产品编号的报工图片
                        'audit_images' => [],
                        'audit_videos' => []
                    ];
                }
            } else {
                // 如果没有产品编号信息，创建一个默认的
                $productItems[] = [
                    'item_no' => '未指定编号',
                    'images' => $images, // 使用全局的报工图片
                    'audit_images' => [],
                    'audit_videos' => []
                ];
            }
            
            // 从产品编号审核图片表获取审核图片和视频，按产品编号分组
            $itemAuditFiles = Db::name('scanwork_item_audit_image')
                ->alias('iai')
                ->join('scanwork_product_item pi', 'iai.item_id = pi.id')
                ->where('iai.report_id', $record['id'])
                ->field('iai.*, pi.item_no')
                ->select();
            
            $rejectImages = [];
            $rejectVideos = [];
            $groupedAuditFiles = [];
            
            foreach ($itemAuditFiles as $file) {
                $url = $file['image_url'];
                if (strpos($url, 'http') !== 0) {
                    $url = request()->domain() . $url;
                }
                
                $itemNo = $file['item_no'];
                if (!isset($groupedAuditFiles[$itemNo])) {
                    $groupedAuditFiles[$itemNo] = [
                        'audit_images' => [],
                        'audit_videos' => []
                    ];
                }
                
                // 根据文件扩展名判断是图片还是视频
                $extension = strtolower(pathinfo($url, PATHINFO_EXTENSION));
                if (in_array($extension, ['mp4', 'avi', 'mov', 'wmv', 'flv', '3gp', 'webm'])) {
                    $groupedAuditFiles[$itemNo]['audit_videos'][] = [
                        'video_url' => $url,
                        'thumb_url' => '',
                        'upload_user_name' => '管理员',
                        'createtime_text' => date('Y-m-d H:i:s', $file['createtime'])
                    ];
                    $rejectVideos[] = $url;
                } else {
                    $groupedAuditFiles[$itemNo]['audit_images'][] = [
                        'image_url' => $url,
                        'upload_user_name' => '管理员',
                        'createtime_text' => date('Y-m-d H:i:s', $file['createtime'])
                    ];
                    $rejectImages[] = $url;
                }
            }
            
            // 将审核图片和视频分配给对应的产品编号
            foreach ($productItems as &$item) {
                $itemNo = $item['item_no'];
                if (isset($groupedAuditFiles[$itemNo])) {
                    $item['audit_images'] = $groupedAuditFiles[$itemNo]['audit_images'];
                    $item['audit_videos'] = $groupedAuditFiles[$itemNo]['audit_videos'];
                }
            }
            
            $record['product_items'] = $productItems;
            $record['reject_images'] = $rejectImages;
            $record['reject_videos'] = $rejectVideos;
            
            // 普通报工没有视频字段
            $record['videos'] = [];
            
            // 格式化时间
            $record['createtime_text'] = date('Y-m-d H:i:s', $record['createtime']);
            $record['status_text'] = $record['status'] == 1 ? '已确认' : '待确认';
            $record['type'] = 'piece'; // 标记为计件报工
        }
        
        // 获取主动报工记录
        $activeRecords = Db::name('scanwork_active_report')
            ->alias('ar')
            ->join('scanwork_order o', 'ar.order_id = o.id')
            ->join('scanwork_model m', 'ar.model_id = m.id')
            ->join('scanwork_product p', 'ar.product_id = p.id')
            ->join('scanwork_process pr', 'ar.process_id = pr.id')
            ->where('ar.user_id', $user['id'])
            ->where('ar.status', '>', 0)
            ->field('ar.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name')
            ->order('ar.createtime desc')
            ->select();
        
        // 为主动报工记录补充信息
        foreach ($activeRecords as &$record) {
            // 从产品编号图片表获取员工上传的图片和产品编号信息
            $productItemImages = Db::name('scanwork_active_report_product_item')
                ->where('active_report_id', $record['id'])
                ->select();
            
            $images = [];
            $productItems = [];
            $groupedItems = [];
            
            foreach ($productItemImages as $img) {
                if (strpos($img['image_url'], 'http') !== 0) {
                    $img['image_url'] = request()->domain() . $img['image_url'];
                }
                $images[] = $img['image_url'];
                
                // 按产品编号分组
                $itemNo = $img['item_no'];
                if (!isset($groupedItems[$itemNo])) {
                    $groupedItems[$itemNo] = [
                        'item_no' => $itemNo,
                        'images' => [],
                        'audit_images' => [],
                        'audit_videos' => []
                    ];
                }
                // 避免重复添加相同的图片
                if (!in_array($img['image_url'], $groupedItems[$itemNo]['images'])) {
                    $groupedItems[$itemNo]['images'][] = $img['image_url'];
                }
            }
            $record['images'] = $images;
            
            // 获取每个产品编号对应的审核图片和视频
            foreach ($groupedItems as $itemNo => &$item) {
                $item['audit_images'] = [];
                $item['audit_videos'] = [];
                
                // 获取该产品编号对应的审核图片（从scanwork_active_report_image表）
            $auditImages = Db::name('scanwork_active_report_image')
                ->where('active_report_id', $record['id'])
                    ->where('image_type', 2) // 2: 审核图片
                    ->where('item_no', $itemNo) // 按产品编号筛选qiangx
                ->select();
            
                foreach ($auditImages as $auditImage) {
                    $imageUrl = $auditImage['image_url'];
                    if (strpos($imageUrl, 'http') !== 0) {
                        $imageUrl = request()->domain() . $imageUrl;
                    }
                    // 避免重复添加相同的审核图片
                    $auditImageData = [
                        'image_url' => $imageUrl,
                        'upload_user_name' => '管理员',
                        'createtime_text' => date('Y-m-d H:i:s', $auditImage['createtime'])
                    ];
                    if (!in_array($auditImageData, $item['audit_images'])) {
                        $item['audit_images'][] = $auditImageData;
                    }
                }
                
                // 获取该产品编号的审核视频（从scanwork_active_report_video表）
                $auditVideos = Db::name('scanwork_active_report_video')
                ->where('active_report_id', $record['id'])
                    ->where('video_type', 2) // 2: 审核视频
                    ->where('item_no', $itemNo) // 按产品编号筛选
                ->select();
            
                foreach ($auditVideos as $auditVideo) {
                    $videoUrl = $auditVideo['video_url'];
                    if (strpos($videoUrl, 'http') !== 0) {
                        $videoUrl = request()->domain() . $videoUrl;
                    }
                    // 避免重复添加相同的审核视频
                    $auditVideoData = [
                        'video_url' => $videoUrl,
                        'thumb_url' => '',
                        'upload_user_name' => '管理员',
                        'createtime_text' => date('Y-m-d H:i:s', $auditVideo['createtime'])
                    ];
                    if (!in_array($auditVideoData, $item['audit_videos'])) {
                        $item['audit_videos'][] = $auditVideoData;
                    }
                }
            }
            
            $record['product_items'] = array_values($groupedItems);
            
            // 调试日志
            error_log("主动报工产品编号详情 - 报工ID: {$record['id']}, 产品编号数量: " . count($groupedItems));
            foreach ($groupedItems as $itemNo => $item) {
                error_log("产品编号: {$itemNo}, 报工图片数量: " . count($item['images']) . ", 审核图片数量: " . count($item['audit_images']) . ", 审核视频数量: " . count($item['audit_videos']));
                error_log("产品编号 {$itemNo} 的报工图片: " . json_encode($item['images']));
                error_log("产品编号 {$itemNo} 的审核图片: " . json_encode($item['audit_images']));
            }
            
            // 为了兼容性，保留原有的reject_images字段（从product_items中提取）
            $rejectImages = [];
            $rejectVideos = [];
            foreach ($groupedItems as $item) {
                foreach ($item['audit_images'] as $auditImg) {
                    $rejectImages[] = $auditImg['image_url'];
                }
                foreach ($item['audit_videos'] as $auditVideo) {
                    $rejectVideos[] = $auditVideo['video_url'];
                }
            }
            $record['reject_images'] = $rejectImages;
            $record['reject_videos'] = $rejectVideos;
            
            // 主动报工没有视频字段
            $record['videos'] = [];
            
            $record['createtime_text'] = date('Y-m-d H:i:s', $record['createtime']);
            $record['status_text'] = $record['status'] == 1 ? '已确认' : '待确认';
            $record['type'] = 'active'; // 标记为主动报工
            $record['wage'] = $record['total_wage']; // 统一工资字段
        }
        
        // 合并两种记录
        $allRecords = array_merge($normalRecords, $activeRecords);
        
        // 按创建时间排序
        usort($allRecords, function($a, $b) {
            return $b['createtime'] - $a['createtime'];
        });
        
        $this->success('获取成功', [
            'list' => $allRecords,
            'total' => count($allRecords),
            'page' => 1,
            'limit' => count($allRecords)
        ]);
    }

    /**
     * 获取工资统计
     */
    public function getWageStats()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $month = $this->request->param('month', date('Y-m'));
        
        $startTime = strtotime($month . '-01 00:00:00');
        $endTime = strtotime($month . '-' . date('t', $startTime) . ' 23:59:59');
        
        // 获取普通报工记录
        $normalReports = Db::name('scanwork_report')
            ->alias('r')
            ->join('scanwork_allocation a', 'r.allocation_id = a.id')
            ->join('scanwork_order o', 'a.order_id = o.id')
            ->join('scanwork_model m', 'a.model_id = m.id')
            ->join('scanwork_product p', 'm.product_id = p.id')
            ->join('scanwork_process pr', 'a.process_id = pr.id')
            ->where('r.user_id', $user['id'])
            ->where('r.status', 1)
            ->where('r.createtime', 'between', [$startTime, $endTime])
            ->field('r.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name, "normal" as report_type')
            ->select();
        
        // 获取主动报工记录
        $activeReports = Db::name('scanwork_active_report')
            ->alias('ar')
            ->join('scanwork_order o', 'ar.order_id = o.id')
            ->join('scanwork_model m', 'ar.model_id = m.id')
            ->join('scanwork_product p', 'ar.product_id = p.id')
            ->join('scanwork_process pr', 'ar.process_id = pr.id')
            ->where('ar.user_id', $user['id'])
            ->where('ar.status', 1)
            ->where('ar.createtime', 'between', [$startTime, $endTime])
            ->field('ar.id, ar.order_id, ar.product_id, ar.model_id, ar.process_id, ar.user_id, ar.quantity, ar.work_hours, ar.piece_wage, ar.time_wage, ar.total_wage as wage, ar.work_date, ar.remark, ar.status, ar.createtime, ar.updatetime, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name, "active" as report_type')
            ->select();
        
        // 合并两种报工记录
        $allReports = array_merge($normalReports, $activeReports);
        
        // 按创建时间排序
        usort($allReports, function($a, $b) {
            return $b['createtime'] - $a['createtime'];
        });
        
        // 为每条记录添加时间格式化
        foreach ($allReports as &$report) {
            $report['createtime_text'] = date('Y-m-d H:i:s', $report['createtime']);
        }
        
        $totalWage = array_sum(array_column($allReports, 'wage'));
        $totalQuantity = array_sum(array_column($allReports, 'quantity'));
        
        // 如果没有数据，返回默认结构
        if (empty($allReports)) {
        $this->success('获取成功', [
                'reports' => [],
                'total_quantity' => 0,
                'total_wage' => 0,
                'start_date' => date('Y-m-01', $startTime),
                'end_date' => date('Y-m-d', $endTime),
                'message' => '本月暂无报工记录'
            ]);
        } else {
            $this->success('获取成功', [
                'reports' => $allReports,
                'total_quantity' => $totalQuantity,
            'total_wage' => $totalWage,
            'start_date' => date('Y-m-01', $startTime),
            'end_date' => date('Y-m-d', $endTime)
        ]);
        }
    }

    /**
     * 获取统计图表数据
     */
    public function getStats()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $workerId = $this->auth->id;
        
        // 获取最近7天的数据
        $dates = [];
        $quantities = [];
        $wages = [];
        
        for ($i = 6; $i >= 0; $i--) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $dates[] = $date;
            
            // 普通报工数量
            $normalQuantity = Db::name('scanwork_report')
                ->where('user_id', $workerId)
                ->where('status', 1)
                ->where('createtime', 'between', [strtotime($date), strtotime($date . ' 23:59:59')])
                ->sum('quantity');
            
            // 主动报工数量
            $activeQuantity = Db::name('scanwork_active_report')
                ->where('user_id', $workerId)
                ->where('status', 1)
                ->where('createtime', 'between', [strtotime($date), strtotime($date . ' 23:59:59')])
                ->sum('quantity');
            
            // 普通报工工资
            $normalWage = Db::name('scanwork_report')
                ->where('user_id', $workerId)
                ->where('status', 1)
                ->where('createtime', 'between', [strtotime($date), strtotime($date . ' 23:59:59')])
                ->sum('wage');
            
            // 主动报工工资
            $activeWage = Db::name('scanwork_active_report')
                ->where('user_id', $workerId)
                ->where('status', 1)
                ->where('createtime', 'between', [strtotime($date), strtotime($date . ' 23:59:59')])
                ->sum('total_wage');
            
            $quantities[] = intval($normalQuantity + $activeQuantity);
            $wages[] = floatval($normalWage + $activeWage);
        }
        
        $this->success('获取成功', [
            'dates' => $dates,
            'quantities' => $quantities,
            'wages' => $wages
        ]);
    }

    /**
     * 获取用户的计时任务列表
     */
    /**
     * 获取用户计时任务列表 - 按照PC端方式实现
     */
    public function getTimeTasks()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
            $workerId = $this->auth->id;
        
        // 查询计时任务，并关联获取订单、型号、工序、产品信息
            $tasks = Db::name('scanwork_tallocationtime')
                ->alias('t')
                ->join('scanwork_order o', 't.order_id = o.id')
            ->join('scanwork_model m', 't.model_id = m.id')
            ->join('scanwork_process pr', 't.process_id = pr.id')
            ->join('scanwork_product prd', 'm.product_id = prd.id')
                ->where('t.user_id', $workerId)
                ->where('t.status', 0)
            ->field([
                't.*',
                'o.order_no',
                'COALESCE(o.order_name, o.order_no) as order_name',
                'prd.name as product_name',
                'm.name as model_name',
                'pr.name as process_name'
            ])
                ->order('t.work_date desc')
                ->select();
            
        // 处理数据
            foreach ($tasks as &$task) {
            $task['work_date_text'] = $task['work_date'];
            $task['createtime_text'] = date('Y-m-d H:i', $task['createtime']);
            
            // 计算任务状态
            if ($task['start_time'] && $task['end_time']) {
                $task['task_status'] = 'completed';
                $task['status_text'] = '已完成';
            } elseif ($task['start_time']) {
                $task['task_status'] = 'in_progress';
                $task['status_text'] = '进行中';
            } else {
                $task['task_status'] = 'pending';
                $task['status_text'] = '待开始';
            }
            }
            
            $this->success('获取成功', $tasks);
    }

    /**
     * 开始计时任务
     */
    public function startTimeTask()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        if (!$this->request->isPost()) {
            $this->error('请求方式错误');
        }
        
        try {
        $workerId = $this->auth->id;
            $taskId = $this->request->post('task_id');
            $startTime = $this->request->post('start_time');
            
            if (!$taskId || !$startTime) {
                $this->error('参数不完整');
            }
            
            // 查找任务
            $task = Db::name('scanwork_tallocationtime')
                ->where('id', $taskId)
                ->where('user_id', $workerId)
                ->where('status', 0)
                ->find();
            
            if (!$task) {
                $this->error('任务不存在或无权限');
            }
            
            // 检查是否已经开始
            if ($task['start_time']) {
                $this->error('任务已经开始，不能重复开始');
            }
            
            // 更新开始时间
            Db::name('scanwork_tallocationtime')
                ->where('id', $taskId)
                ->update([
                    'start_time' => $startTime,
                    'updatetime' => time()
                ]);
            
            $this->success('计时任务开始成功');
            
        } catch (\Exception $e) {
            $this->error('开始计时任务失败：' . $e->getMessage());
        }
    }
    
    /**
     * 结束计时任务
     */
    public function endTimeTask()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        if (!$this->request->isPost()) {
            $this->error('请求方式错误');
        }
        
        try {
            $workerId = $this->auth->id;
            $taskId = $this->request->post('task_id');
            $endTime = $this->request->post('end_time');
            $totalHours = floatval($this->request->post('total_hours'));
            $remark = $this->request->post('remark', '');
            
            if (!$taskId || !$endTime || $totalHours <= 0) {
                    $this->error('参数不完整');
                }
                
            // 查找任务
            $task = Db::name('scanwork_tallocationtime')
                ->where('id', $taskId)
                ->where('user_id', $workerId)
                ->where('status', 0)
                ->find();
            
            if (!$task) {
                $this->error('任务不存在或无权限');
            }
            
            // 检查是否已经开始
            if (!$task['start_time']) {
                $this->error('任务尚未开始，请先开始任务');
            }
            
            // 更新结束时间和工时
            Db::name('scanwork_tallocationtime')
                ->where('id', $taskId)
                ->update([
                    'end_time' => $endTime,
                    'total_hours' => $totalHours,
                    'updatetime' => time()
                ]);
            
            $this->success('计时任务结束成功');
            
        } catch (\Exception $e) {
            $this->error('结束计时任务失败：' . $e->getMessage());
        }
    }
    
/**
     * 获取计时任务详情
     */
    public function getTimeTaskDetail()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        try {
            $workerId = $this->auth->id;
            $taskId = $this->request->get('task_id');
            
            if (!$taskId) {
                $this->error('缺少任务ID');
            }
            
            // 查询任务详情，关联订单、型号、工序、产品信息
            $task = Db::name('scanwork_tallocationtime')
                ->alias('t')
                ->join('scanwork_order o', 't.order_id = o.id')
                ->join('scanwork_model m', 't.model_id = m.id')
                ->join('scanwork_process p', 't.process_id = p.id')
                ->join('scanwork_product prd', 'm.product_id = prd.id')
                ->where('t.id', $taskId)
                ->where('t.user_id', $workerId)
                ->field('t.*, o.order_name, o.order_no, m.name as model_name, p.name as process_name, prd.name as product_name')
                ->find();
            
            if (!$task) {
                $this->error('任务不存在或无权限');
            }
            
            // 格式化数据
            $task['work_date_text'] = $task['work_date'] ? date('Y-m-d', strtotime($task['work_date'])) : '';
            $task['createtime_text'] = date('Y-m-d H:i', $task['createtime']);
            
            // 计算任务状态
            if ($task['start_time'] && $task['end_time']) {
                $task['task_status'] = 'completed';
                $task['status_text'] = '已完成';
            } elseif ($task['start_time']) {
                $task['task_status'] = 'in_progress';
                $task['status_text'] = '进行中';
            } else {
                $task['task_status'] = 'pending';
                $task['status_text'] = '待开始';
            }
            
            $this->success('获取成功', $task);
            
        } catch (\Exception $e) {
            $this->error('获取任务详情失败：' . $e->getMessage());
        }
    }
    
    /**
     * 提交计时报工
     */
    public function submitTimeReport()
    {
        error_log("=== 计时报工开始 ===");
        
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $workerId = $user['id'];
        
        error_log("计时报工 - 用户ID: " . $workerId);
        
        // 获取参数
        $taskId = intval($this->request->post('task_id', 0));
        $workDate = $this->request->post('work_date', '');
        $startTime = $this->request->post('start_time', '');
        $endTime = $this->request->post('end_time', '');
        $totalHours = floatval($this->request->post('total_hours', 0));
        $remark = $this->request->post('remark', '');
        $imageUrls = $this->request->post('image_urls/a', []); // 图片URL数组
        
        error_log("计时报工 - 参数: task_id=$taskId, work_date=$workDate, start_time=$startTime, end_time=$endTime, total_hours=$totalHours");
        error_log("计时报工 - remark: " . $remark);
        error_log("计时报工 - image_urls数量: " . count($imageUrls));
        
        // 验证参数
        if (empty($taskId)) {
            $this->error('任务ID不能为空');
        }
        
        if (empty($workDate) || empty($startTime) || empty($endTime) || $totalHours <= 0) {
            $this->error('工作日期、开始时间、结束时间、工时不能为空');
        }
        
        try {
            // 验证任务是否存在且属于当前用户
            $task = Db::name('scanwork_tallocationtime')->where('id', $taskId)->find();
            if (!$task) {
                $this->error('任务不存在');
            }
            
            if ($task['user_id'] != $workerId) {
                $this->error('无权操作此任务');
            }
            
            error_log("计时报工 - 任务验证通过");
                
                Db::startTrans();
            
            try {
                // 创建计时报工记录
                $reportData = [
                    'tallocationtime_id' => $taskId,
                    'user_id' => $workerId,
                    'work_date' => $workDate,
                    'start_time' => $startTime,
                    'end_time' => $endTime,
                    'total_hours' => $totalHours,
                    'remark' => $remark,
                    'status' => 0, // 待确认
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                $reportId = Db::name('scanwork_treporttime')->insertGetId($reportData);
                error_log("计时报工 - 报工记录创建成功，ID: " . $reportId);
                
                // 保存图片
                if (!empty($imageUrls) && is_array($imageUrls)) {
                    // 转换本地图片为七牛云URL
                    $cloudImageUrls = $this->convertLocalImagesToCloud($imageUrls);
                    
                    foreach ($cloudImageUrls as $imageUrl) {
                        try {
                            // 保存图片记录
                            $imageData = [
                                'report_id' => $reportId,
                                'image_url' => $imageUrl,
                                'upload_user_id' => $workerId,
                                'createtime' => time()
                            ];
                            
                            Db::name('scanwork_treporttime_image')->insert($imageData);
                            error_log("计时报工 - 图片记录保存成功: " . $imageUrl);
                            
                        } catch (\Exception $e) {
                            error_log("计时报工 - 图片保存失败: " . $e->getMessage());
                            // 不抛出异常，继续执行
                        }
                    }
                    error_log("计时报工 - 图片保存完成，数量: " . count($cloudImageUrls));
                }
                
                // 更新任务状态为已完成
                Db::name('scanwork_tallocationtime')
                    ->where('id', $taskId)
                    ->update([
                        'status' => 1, // 已完成
                    'updatetime' => time()
                ]);
                
                Db::commit();
                error_log("计时报工 - 提交成功");
                
                $response = [
                    'report_id' => $reportId,
                    'task_id' => $taskId
                ];
                
                $this->success('计时报工提交成功，等待审核', $response);
                
            } catch (\Exception $e) {
                Db::rollback();
                error_log("计时报工失败 - 数据库异常: " . $e->getMessage());
                $this->error('报工失败：' . $e->getMessage());
        }
        
        } catch (\Exception $e) {
            error_log("计时报工失败 - 验证异常: " . $e->getMessage());
            $this->error('报工失败：' . $e->getMessage());
        }
    }

    /**
     * 获取计时报工记录
     */
    public function getTimeRecords()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        try {
            $workerId = $this->auth->id;
            $records = Db::name('scanwork_treporttime')
                ->alias('tr')
                ->join('scanwork_tallocationtime ta', 'tr.tallocationtime_id = ta.id')
                ->join('scanwork_order o', 'ta.order_id = o.id')
                ->where('tr.user_id', $workerId)
                ->field('tr.*, o.order_name')
                ->order('tr.work_date desc')
                ->select();
            
            foreach ($records as &$record) {
                $record['work_date_text'] = date('Y-m-d', strtotime($record['work_date']));
                $record['createtime_text'] = date('Y-m-d H:i:s', $record['createtime']);
                $record['status_text'] = $record['status'] == 1 ? '已确认' : '待确认';
            }
            
            $this->success('获取成功', $records);
        } catch (Exception $e) {
            $this->error('获取计时报工记录失败：' . $e->getMessage());
        }
    }

    /**
     * 获取计时工资统计
     */
    public function getTimeWage()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        try {
            $workerId = $this->auth->id;
            $wages = Db::name('scanwork_twage')
                ->alias('tw')
                ->join('scanwork_tallocationtime ta', 'tw.tallocationtime_id = ta.id')
                ->join('scanwork_order o', 'ta.order_id = o.id')
                ->where('tw.user_id', $workerId)
                ->field('tw.*, o.order_name')
                ->order('tw.work_date desc')
                ->select();
            
            foreach ($wages as &$wage) {
                $wage['work_date_text'] = date('Y-m-d', strtotime($wage['work_date']));
                $wage['createtime_text'] = date('Y-m-d H:i:s', $wage['createtime']);
                $wage['status_text'] = $wage['status'] == 1 ? '已确认' : '待确认';
            }
            
            $this->success('获取成功', $wages);
        } catch (Exception $e) {
            $this->error('获取计时工资统计失败：' . $e->getMessage());
        }
    }

    /**
     * 主动报工
     */
    public function activeReport()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $workerId = $this->auth->id;
        
        if ($this->request->isPost()) {
            try {
                Db::startTrans();
                
                $order_id = $this->request->post('order_id');
                $order_model = $this->request->post('order_model'); // 格式：model_id:process_id
                $quantity = intval($this->request->post('quantity'));
                $work_hours = floatval($this->request->post('work_hours'));
                $start_time = $this->request->post('start_time');
                $end_time = $this->request->post('end_time');
                $work_date = $this->request->post('work_date');
                $remark = $this->request->post('remark');
                $product_items = $this->request->post('product_items/a'); // 产品编号和图片数据
                $images = $this->request->post('images/a'); // 通用图片数据
                
                // 解析产品型号和工序ID
                $model_process = explode(':', $order_model);
                $model_id = $model_process[0];
                $process_id = $model_process[1];
                
                if (!$order_id || !$model_id || !$process_id || !$work_date) {
                    $this->error('请填写完整信息');
                }
                
                if ($quantity <= 0) {
                    $this->error('数量必须大于0');
                }
                
                if ($work_hours <= 0) {
                    $this->error('工作时长必须大于0');
                }
                
                // 检查分配数量和已报工数量，控制主动报工数量
                $allocation = Db::name('scanwork_allocation')
                    ->where('order_id', $order_id)
                    ->where('model_id', $model_id)
                    ->where('process_id', $process_id)
                    ->where('user_id', $workerId)
                    ->find();
                
                if ($allocation) {
                    // 计算剩余可报工数量
                    $remainingQuantity = max(0, $allocation['quantity'] - $allocation['reported_quantity']);
                    
                    if ($quantity > $remainingQuantity) {
                        $this->error("报工数量超出限制！分配数量：{$allocation['quantity']}，已报工：{$allocation['reported_quantity']}，剩余可报工：{$remainingQuantity}");
                    }
                }
                
                // 验证订单是否存在
                $order = Db::name('scanwork_order')->where('id', $order_id)->find();
                if (!$order) {
                    $this->error('订单不存在');
                }
                
                // 验证产品型号是否存在
                $model = Db::name('scanwork_model')->where('id', $model_id)->find();
                if (!$model) {
                    $this->error('产品型号不存在');
                }
                
                // 验证工序是否存在
                $process = Db::name('scanwork_process')->where('id', $process_id)->find();
                if (!$process) {
                    $this->error('工序不存在');
                }
                
                // 查找工价
                $processPrice = Db::name('scanwork_process_price')->where([
                    'model_id' => $model_id,
                    'process_id' => $process_id
                ])->find();
                
                if (!$processPrice) {
                    $this->error('该产品型号和工序的工价未设置');
                }
                
                // 计算计件工资
                $piece_wage = round($quantity * $processPrice['price'], 2);
                
                // 计算计时工资
                $time_wage = round($work_hours * $processPrice['time_price'], 2);
                
                // 总工资 = 计件工资 + 计时工资
                $total_wage = $piece_wage + $time_wage;
                
                // 为每个产品编号创建独立的报工记录
                if (!empty($product_items) && is_array($product_items)) {
                    foreach ($product_items as $item) {
                        $item_no = $item['item_no'];
                        $item_images = $item['images'];
                        
                        // 转换本地图片为七牛云URL
                        $cloudItemImages = $this->convertLocalImagesToCloud($item_images);
                        
                        // 为每个产品编号创建独立的报工记录
                        $activeReportId = Db::name('scanwork_active_report')->insertGetId([
                    'order_id' => $order_id,
                    'product_id' => $model['product_id'],
                    'model_id' => $model_id,
                    'process_id' => $process_id,
                    'user_id' => $workerId,
                            'quantity' => 1, // 每个产品编号数量为1
                    'work_hours' => $work_hours,
                    'start_time' => $start_time ?: '',
                    'end_time' => $end_time ?: '',
                            'piece_wage' => $piece_wage / $quantity, // 平均分配计件工资
                            'time_wage' => $time_wage / $quantity, // 平均分配计时工资
                            'total_wage' => $total_wage / $quantity, // 平均分配总工资
                    'work_date' => $work_date,
                            'remark' => $remark . ' (产品编号: ' . $item_no . ')',
                    'status' => 0, // 待审核
                    'createtime' => time(),
                    'updatetime' => time()
                ]);
                
                        // 保存该产品编号的图片
                        foreach ($cloudItemImages as $image_url) {
                            Db::name('scanwork_active_report_product_item')->insert([
                                'active_report_id' => $activeReportId,
                                'item_no' => $item_no,
                                'image_url' => $image_url,
                                'createtime' => time()
                            ]);
                        }
                    }
                } else {
                    // 如果没有产品编号，创建一条普通的报工记录
                    $activeReportId = Db::name('scanwork_active_report')->insertGetId([
                        'order_id' => $order_id,
                        'product_id' => $model['product_id'],
                        'model_id' => $model_id,
                        'process_id' => $process_id,
                        'user_id' => $workerId,
                        'quantity' => $quantity,
                        'work_hours' => $work_hours,
                        'start_time' => $start_time ?: '',
                        'end_time' => $end_time ?: '',
                        'piece_wage' => $piece_wage,
                        'time_wage' => $time_wage,
                        'total_wage' => $total_wage,
                        'work_date' => $work_date,
                        'remark' => $remark,
                        'status' => 0, // 待审核
                        'createtime' => time(),
                        'updatetime' => time()
                    ]);
                }
                
                // 保存通用图片数据（计时图片）
                if (!empty($images) && is_array($images)) {
                    // 转换本地图片为七牛云URL
                    $cloudImages = $this->convertLocalImagesToCloud($images);
                    
                    foreach ($cloudImages as $image_url) {
                        Db::name('scanwork_active_report_image')->insert([
                            'active_report_id' => $activeReportId,
                            'image_url' => $image_url,
                            'image_type' => 1, // 员工上传的图片
                            'createtime' => time()
                        ]);
                    }
                }
                
                Db::commit();
                return json(['code' => 1, 'msg' => '主动报工提交成功，等待审核']);
                
            } catch (Exception $e) {
                Db::rollback();
                return json(['code' => 0, 'msg' => '主动报工提交失败：' . $e->getMessage()]);
            }
        }
        
        return json(['code' => 0, 'msg' => '请求方式错误']);
    }

    /**
     * 获取订单列表
     */
    public function getOrders()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $orders = Db::name('scanwork_order')
            ->order('createtime desc')
            ->select();
        
        foreach ($orders as &$order) {
            $order['createtime_text'] = date('Y-m-d H:i:s', $order['createtime']);
        }
        
        $this->success('获取成功', $orders);
    }

    /**
     * 获取产品型号列表
     */
    public function getModels()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        try {
            $models = Db::name('scanwork_model')
                ->alias('m')
                ->join('scanwork_product p', 'm.product_id = p.id')
                ->field('m.id, m.name, p.name as product_name')
                ->order('p.name, m.name')
                ->select();
            
            $this->success('获取成功', $models);
        } catch (Exception $e) {
            $this->error('获取产品型号列表失败：' . $e->getMessage());
        }
    }

    /**
     * 获取工序列表
     */
    public function getProcesses()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        try {
            $processes = Db::name('scanwork_process')
                ->where('status', 1)
                ->order('name')
                ->select();
            
            $this->success('获取成功', $processes);
        } catch (Exception $e) {
            $this->error('获取工序列表失败：' . $e->getMessage());
        }
    }

    /**
     * 获取订单型号
     */
        public function getOrderModels()
    {
        // 暂时移除登录检查，用于测试
        // if (!$this->auth->isLogin()) {
        //     $this->error('未登录', null, 401);
        // }
        
        $orderId = $this->request->get('order_id');
        error_log("getOrderModels - orderId: " . $orderId);
        
        if (!$orderId) {
            $this->error('参数错误');
        }

        try {
            error_log("getOrderModels - 开始查询订单型号，orderId: " . $orderId);
            
            // 先测试基本查询
            $orderModels = Db::name('scanwork_order_model')
                ->where('order_id', $orderId)
                ->select();
            
            error_log("getOrderModels - 基本查询到订单型号数量: " . count($orderModels));
            
            if (empty($orderModels)) {
                error_log("getOrderModels - 没有找到订单型号，返回空数组");
                return json(['code' => 1, 'msg' => '获取成功', 'data' => []]);
            }
            
            error_log("getOrderModels - 开始查询工序");
            // 获取所有工序
            $processes = Db::name('scanwork_process')
                ->where('status', 1)
                ->order('name')
                ->select();
                
            error_log("getOrderModels - 查询到工序数量: " . count($processes));
            
            error_log("getOrderModels - 开始处理数据");
            $result = [];
            foreach ($orderModels as $orderModel) {
                error_log("getOrderModels - 处理订单型号: " . json_encode($orderModel));
                foreach ($processes as $process) {
                    error_log("getOrderModels - 处理工序: " . json_encode($process));
                    // 检查是否有该产品型号和工序的工价设置
                    $processPrice = Db::name('scanwork_process_price')->where([
                        'model_id' => $orderModel['model_id'],
                        'process_id' => $process['id']
                    ])->find();
                    
                    error_log("getOrderModels - 工价查询结果: " . json_encode($processPrice));
                    
                    if ($processPrice) {
                        error_log("getOrderModels - 开始获取产品信息");
                        // 获取产品信息
                        $model = Db::name('scanwork_model')->where('id', $orderModel['model_id'])->find();
                        $product = Db::name('scanwork_product')->where('id', $model['product_id'])->find();
                        
                        error_log("getOrderModels - 型号信息: " . json_encode($model));
                        error_log("getOrderModels - 产品信息: " . json_encode($product));
                        
                        // 计算已分工数量
                        $allocatedQuantity = Db::name('scanwork_allocation')
                            ->where([
                                'order_id' => $orderId,
                                'model_id' => $orderModel['model_id'],
                                'process_id' => $process['id']
                            ])
                            ->sum('quantity') ?: 0;
                        
                        // 计算主动报工数量
                        $activeReportQuantity = Db::name('scanwork_active_report')
                            ->where([
                                'order_id' => $orderId,
                                'model_id' => $orderModel['model_id'],
                                'process_id' => $process['id']
                            ])
                            ->sum('quantity') ?: 0;
                        
                        $result[] = [
                            'model_id' => $orderModel['model_id'],
                            'model_name' => $model['name'],
                            'product_name' => $product['name'],
                            'process_id' => $process['id'],
                            'process_name' => $process['name'],
                            'order_quantity' => $orderModel['quantity'],
                            'allocated_quantity' => $allocatedQuantity, // 已分工数量
                            'active_report_quantity' => $activeReportQuantity, // 主动报工数量
                            'piece_price' => $processPrice['price'],
                            'time_price' => $processPrice['time_price'],
                            'display_name' => $product['name'] . ' - ' . $model['name'] . ' (' . $process['name'] . ')'
                        ];
                        error_log("getOrderModels - 添加结果项: " . json_encode(end($result)));
                    }
                }
            }

            error_log("getOrderModels - 最终结果数量: " . count($result));
            return json(['code' => 1, 'msg' => '获取成功', 'data' => $result]);
        } catch (Exception $e) {
            $errorMsg = '获取订单型号失败：' . $e->getMessage();
            error_log("getOrderModels - 异常: " . $e->getMessage());
            error_log("getOrderModels - 异常堆栈: " . $e->getTraceAsString());
            return json(['code' => 0, 'msg' => $errorMsg, 'data' => null]);
        } catch (\Throwable $e) {
            $errorMsg = '获取订单型号失败：' . $e->getMessage();
            error_log("getOrderModels - Throwable异常: " . $e->getMessage());
            error_log("getOrderModels - Throwable异常堆栈: " . $e->getTraceAsString());
            return json(['code' => 0, 'msg' => $errorMsg, 'data' => null]);
        }
    }



    /**
     * 获取工序工价信息
     */
    public function getProcessPrice()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $model_id = $this->request->get('model_id');
        $process_id = $this->request->get('process_id');
        
        if (!$model_id || !$process_id) {
            $this->error('参数错误');
        }
        
        try {
            $processPrice = Db::name('scanwork_process_price')->where([
                'model_id' => $model_id,
                'process_id' => $process_id
            ])->find();
            
            if (!$processPrice) {
                $this->error('该产品型号和工序的工价未设置');
            }
            
            $this->success('获取成功', [
                'price' => floatval($processPrice['price']),
                'time_price' => floatval($processPrice['time_price'])
            ]);
        } catch (Exception $e) {
            $this->error('获取工价信息失败：' . $e->getMessage());
        }
    }

    /**
     * 获取订单信息
     */
    public function getOrderInfo()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        $order_id = $this->request->get('order_id');
        if (!$order_id) {
            $this->error('参数错误');
        }
        
        try {
            $order = Db::name('scanwork_order')->where('id', $order_id)->find();
            if (!$order) {
                $this->error('订单不存在');
            }
            
            // 计算已分配数量
            $allocatedQuantity = Db::name('scanwork_allocation')
                ->where('order_id', $order_id)
                ->sum('quantity');
            
            // 计算已报工数量
            $reportedQuantity = Db::name('scanwork_report')
                ->alias('r')
                ->join('scanwork_allocation a', 'r.allocation_id = a.id')
                ->where('a.order_id', $order_id)
                ->where('r.status', 1)
                ->sum('r.quantity');
            
            $this->success('获取成功', [
                'total_quantity' => $order['total_quantity'],
                'allocated_quantity' => $allocatedQuantity,
                'available_quantity' => max(0, $order['total_quantity'] - $allocatedQuantity - $reportedQuantity)
            ]);
        } catch (Exception $e) {
            $this->error('获取订单信息失败：' . $e->getMessage());
        }
    }

    /**
     * 获取主动报工记录
     */
    public function getActiveReports()
    {
        if (!$this->auth->isLogin()) {
            return json(['code' => 0, 'msg' => '未登录', 'data' => null]);
        }
        
        $workerId = $this->auth->id;
        $page = intval($this->request->get('page', 1));
        $limit = intval($this->request->get('limit', 10));
        
        try {
            $offset = ($page - 1) * $limit;
            
            // 获取主动报工记录
            $reports = Db::name('scanwork_active_report')
                ->alias('ar')
                ->join('scanwork_order o', 'ar.order_id = o.id')
                ->join('scanwork_model m', 'ar.model_id = m.id')
                ->join('scanwork_product p', 'm.product_id = p.id')
                ->join('scanwork_process pr', 'ar.process_id = pr.id')
                ->where('ar.user_id', $workerId)
                ->field('ar.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name')
                ->order('ar.createtime desc')
                ->limit($offset, $limit)
                ->select();
            
            // 获取总数
            $total = Db::name('scanwork_active_report')
                ->where('user_id', $workerId)
                ->count();
            
            // 处理每条记录
            foreach ($reports as &$report) {
                $report['createtime_text'] = date('Y-m-d H:i:s', $report['createtime']);
                $report['status_text'] = $this->getStatusText($report['status']);
                
                // 获取图片数量
                $imageCount = Db::name('scanwork_active_report_product_item')
                    ->where('active_report_id', $report['id'])
                    ->count();
                $report['image_count'] = $imageCount;
            }
            
            return json([
                'code' => 1, 
                'msg' => '获取成功', 
                'data' => [
                    'list' => $reports,
                    'total' => $total,
                    'page' => $page,
                    'limit' => $limit
                ]
            ]);
            
        } catch (Exception $e) {
            return json(['code' => 0, 'msg' => '获取主动报工记录失败：' . $e->getMessage(), 'data' => null]);
        }
    }

    /**
     * 获取主动报工详情
     */
    public function getActiveReportDetail()
    {
        if (!$this->auth->isLogin()) {
            return json(['code' => 0, 'msg' => '未登录', 'data' => null]);
        }
        
        $workerId = $this->auth->id;
        $reportId = intval($this->request->get('id'));
        
        if (!$reportId) {
            return json(['code' => 0, 'msg' => '参数错误', 'data' => null]);
        }
        
        try {
            // 获取报工详情
            $report = Db::name('scanwork_active_report')
                ->alias('ar')
                ->join('scanwork_order o', 'ar.order_id = o.id')
                ->join('scanwork_model m', 'ar.model_id = m.id')
                ->join('scanwork_product p', 'm.product_id = p.id')
                ->join('scanwork_process pr', 'ar.process_id = pr.id')
                ->where('ar.id', $reportId)
                ->where('ar.user_id', $workerId)
                ->field('ar.*, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name')
                ->find();
            
            if (!$report) {
                return json(['code' => 0, 'msg' => '报工记录不存在', 'data' => null]);
            }
            
            $report['createtime_text'] = date('Y-m-d H:i:s', $report['createtime']);
            $report['status_text'] = $this->getStatusText($report['status']);
            
            // 获取产品编号和图片
            $productItems = Db::name('scanwork_active_report_product_item')
                ->where('active_report_id', $reportId)
                ->field('item_no, image_url')
                ->select();
            
            // 按产品编号分组图片
            $groupedItems = [];
            foreach ($productItems as $item) {
                $itemNo = $item['item_no'];
                if (!isset($groupedItems[$itemNo])) {
                    $groupedItems[$itemNo] = [
                        'item_no' => $itemNo,
                        'images' => []
                    ];
                }
                $groupedItems[$itemNo]['images'][] = $item['image_url'];
            }
            
            $report['product_items'] = array_values($groupedItems);
            
            // 获取审核图片和视频（按产品编号分组）
            $auditImages = Db::name('scanwork_active_report_audit_image')
                ->alias('ai')
                ->join('scanwork_active_report_product_item pi', 'ai.product_item_id = pi.id')
                ->where('pi.active_report_id', $reportId)
                ->field('ai.*, pi.item_no')
                ->select();
            
            $auditVideos = Db::name('scanwork_active_report_video')
                ->where('active_report_id', $reportId)
                ->where('video_type', 2) // 只获取管理员审核的视频
                ->select();
            
            // 获取每个产品编号对应的审核图片和视频
            foreach ($groupedItems as $itemNo => &$item) {
                $item['audit_images'] = [];
                $item['audit_videos'] = [];
                
                // 获取该产品编号对应的审核图片（从scanwork_active_report_image表）
                $auditImages = Db::name('scanwork_active_report_image')
                    ->where('active_report_id', $reportId)
                    ->where('image_type', 2) // 2: 审核图片
                    ->where('item_no', $itemNo) // 按产品编号筛选
                    ->select();
                
                foreach ($auditImages as $auditImage) {
                    $item['audit_images'][] = [
                        'image_url' => $auditImage['image_url'],
                        'upload_user_name' => '管理员',
                        'createtime_text' => date('Y-m-d H:i:s', $auditImage['createtime'])
                    ];
                }
                
                // 获取该产品编号的审核视频（从scanwork_active_report_video表）
                $auditVideos = Db::name('scanwork_active_report_video')
                    ->where('active_report_id', $reportId)
                    ->where('video_type', 2) // 2: 审核视频
                    ->where('item_no', $itemNo) // 按产品编号筛选
                    ->select();
                
                foreach ($auditVideos as $auditVideo) {
                    $item['audit_videos'][] = [
                        'video_url' => $auditVideo['video_url'],
                        'thumb_url' => '',
                        'upload_user_name' => '管理员',
                        'createtime_text' => date('Y-m-d H:i:s', $auditVideo['createtime'])
                    ];
                }
            }
            
            $report['product_items'] = array_values($groupedItems);
            
            return json(['code' => 1, 'msg' => '获取成功', 'data' => $report]);
            
        } catch (Exception $e) {
            return json(['code' => 0, 'msg' => '获取报工详情失败：' . $e->getMessage(), 'data' => null]);
        }
    }

    /**
     * 获取状态文本
     */
    private function getStatusText($status)
    {
        switch ($status) {
            case 0:
                return '待审核';
            case 1:
                return '已通过';
            case 2:
                return '已拒绝';
            default:
                return '未知';
        }
    }

    /**
     * 获取消息列表
     */
    public function getMessages()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        
        $page = $this->request->get('page', 1);
        $limit = $this->request->get('limit', 10);
        $type = $this->request->get('type', ''); // 消息类型筛选
        
        $where = ['user_id' => $userId];
        if ($type) {
            $where['type'] = $type;
        }
        
        $list = Db::name('scanwork_message')
            ->where($where)
            ->order('createtime desc')
            ->paginate($limit, false, ['page' => $page]);
            
        $items = $list->items();
        foreach ($items as &$item) {
            $item['createtime_text'] = date('Y-m-d H:i:s', $item['createtime']);
            $item['is_read_text'] = $item['is_read'] ? '已读' : '未读';
        }
        
        $this->success('获取成功', [
            'total' => $list->total(),
            'list' => $items
        ]);
    }

    /**
     * 获取未读消息数量
     */
    public function getUnreadMessageCount()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        
        $count = Db::name('scanwork_message')
            ->where('user_id', $userId)
            ->where('is_read', 0)
            ->count();
        
        $this->success('获取成功', ['count' => $count]);
    }

    /**
     * 标记消息为已读
     */
    public function markMessageRead()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        
        $messageId = $this->request->post('message_id');
        $markAll = $this->request->post('mark_all', 0); // 是否标记所有消息为已读
        
        if ($markAll) {
            // 标记所有消息为已读
            $result = Db::name('scanwork_message')
                ->where('user_id', $userId)
                ->where('is_read', 0)
                ->update(['is_read' => 1, 'readtime' => time()]);
            
            $this->success('标记成功', ['updated_count' => $result]);
        } else {
            // 标记单个消息为已读
            if (!$messageId) {
                $this->error('参数错误');
            }
            
            $result = Db::name('scanwork_message')
                ->where('id', $messageId)
                ->where('user_id', $userId)
                ->update(['is_read' => 1, 'readtime' => time()]);
            
            if ($result) {
                $this->success('标记成功');
            } else {
                $this->error('消息不存在或已标记为已读');
            }
        }
    }

    /**
     * 删除消息
     */
    public function deleteMessage()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        
        $messageId = $this->request->post('message_id');
        $deleteAll = $this->request->post('delete_all', 0); // 是否删除所有已读消息
        
        if ($deleteAll) {
            // 删除所有已读消息
            $result = Db::name('scanwork_message')
                ->where('user_id', $userId)
                ->where('is_read', 1)
                ->delete();
            
            $this->success('删除成功', ['deleted_count' => $result]);
        } else {
            // 删除单个消息
            if (!$messageId) {
                $this->error('参数错误');
            }
            
            $result = Db::name('scanwork_message')
                ->where('id', $messageId)
                ->where('user_id', $userId)
                ->delete();
            
            if ($result) {
                $this->success('删除成功');
            } else {
                $this->error('消息不存在');
            }
        }
    }

    /**
     * 获取最新消息（用于首页显示）
     */
    public function getLatestMessages()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        
        $limit = $this->request->get('limit', 5);
        
        $messages = Db::name('scanwork_message')
            ->where('user_id', $userId)
            ->order('createtime desc')
            ->limit($limit)
            ->select();
            
        foreach ($messages as &$message) {
            $message['createtime_text'] = date('Y-m-d H:i:s', $message['createtime']);
            $message['is_read_text'] = $message['is_read'] ? '已读' : '未读';
        }
        
        $this->success('获取成功', $messages);
    }

    /**
     * 更新订阅消息状态
     */
    public function updateSubscribeStatus()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        $subscribeResult = $this->request->post('subscribe_result');
        
        if (!$subscribeResult) {
            $this->error('参数错误');
        }
        
        // 更新用户的订阅状态
        $updateData = [
            'subscribe_allocation' => isset($subscribeResult['your_allocation_template_id']) && $subscribeResult['your_allocation_template_id'] === 'accept' ? 1 : 0,
            'subscribe_audit' => isset($subscribeResult['your_audit_template_id']) && $subscribeResult['your_audit_template_id'] === 'accept' ? 1 : 0,
            'updatetime' => time()
        ];
        
        $result = Db::name('user')->where('id', $userId)->update($updateData);
        
        if ($result !== false) {
            $this->success('订阅状态更新成功');
        } else {
            $this->error('订阅状态更新失败');
        }
    }

    /**
     * 获取分工通知列表
     */
    public function getAllocationNotifications()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        
        // 获取用户的分工通知
        $notifications = Db::name('scanwork_allocation')
            ->alias('a')
            ->join('scanwork_order o', 'a.order_id = o.id')
            ->join('scanwork_model m', 'a.model_id = m.id')
            ->join('scanwork_product p', 'm.product_id = p.id')
            ->join('scanwork_process pr', 'a.process_id = pr.id')
            ->where('a.user_id', $userId)
            ->where('a.status', 'pending')
            ->field('a.id, a.quantity, a.reported_quantity, a.createtime, a.status, o.order_no, p.name as product_name, m.name as model_name, pr.name as process_name')
            ->order('a.createtime desc')
            ->select();
            
        foreach ($notifications as &$notification) {
            $notification['task_name'] = $notification['product_name'] . '-' . $notification['model_name'];
            $notification['description'] = $notification['process_name'] . '工序';
            $notification['estimated_hours'] = 8; // 默认8小时
            $notification['created_at'] = date('Y-m-d H:i:s', $notification['createtime']);
            $notification['is_read'] = 0; // 默认未读
            // 计算剩余数量
            $notification['remaining_quantity'] = max(0, $notification['quantity'] - $notification['reported_quantity']);
        }
        
        $this->success('获取成功', ['notifications' => $notifications]);
    }

    /**
     * 更新服务通知状态
     */
    public function updateServiceNotificationStatus()
    {
        \think\Log::record('=== updateServiceNotificationStatus 方法开始 ===', 'debug');
        \think\Log::record('请求方法: ' . $this->request->method(), 'debug');
        
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        // 尝试多种方式获取数据
        $rawInput = file_get_contents('php://input');
        $postData = $this->request->post();
        $paramData = $this->request->param();
        
        \think\Log::record('原始输入: ' . $rawInput, 'debug');
        \think\Log::record('POST数据: ' . json_encode($postData, JSON_UNESCAPED_UNICODE), 'debug');
        \think\Log::record('参数数据: ' . json_encode($paramData, JSON_UNESCAPED_UNICODE), 'debug');
        
        // 尝试从不同位置获取数据
        $subscribeStatus = null;
        if (isset($postData['subscribe_status'])) {
            $subscribeStatus = $postData['subscribe_status'];
            \think\Log::record('从POST数据获取到subscribe_status', 'debug');
        } elseif (isset($paramData['subscribe_status'])) {
            $subscribeStatus = $paramData['subscribe_status'];
            \think\Log::record('从参数数据获取到subscribe_status', 'debug');
        } elseif ($rawInput) {
            $jsonData = json_decode($rawInput, true);
            if (isset($jsonData['subscribe_status'])) {
                $subscribeStatus = $jsonData['subscribe_status'];
                \think\Log::record('从JSON输入获取到subscribe_status', 'debug');
            }
        }
        
        // 如果是GET请求，尝试从URL参数获取
        if ($this->request->method() === 'GET') {
            $getData = $this->request->get();
            \think\Log::record('GET数据: ' . json_encode($getData, JSON_UNESCAPED_UNICODE), 'debug');
            if (isset($getData['subscribe_status'])) {
                $subscribeStatus = $getData['subscribe_status'];
                \think\Log::record('从GET数据获取到subscribe_status', 'debug');
            }
        }
        
        // 详细调试信息 - 使用ThinkPHP日志系统
        \think\Log::record('=== updateServiceNotificationStatus 调试开始 ===', 'debug');
        \think\Log::record('userId: ' . $userId, 'debug');
        \think\Log::record('subscribeStatus 类型: ' . gettype($subscribeStatus), 'debug');
        \think\Log::record('subscribeStatus 内容: ' . json_encode($subscribeStatus, JSON_UNESCAPED_UNICODE), 'debug');
        \think\Log::record('subscribeStatus 是否为空: ' . (empty($subscribeStatus) ? 'true' : 'false'), 'debug');
        \think\Log::record('subscribeStatus 是否为数组: ' . (is_array($subscribeStatus) ? 'true' : 'false'), 'debug');
        \think\Log::record('raw POST data: ' . json_encode($this->request->post(), JSON_UNESCAPED_UNICODE), 'debug');
        \think\Log::record('request body: ' . file_get_contents('php://input'), 'debug');
        \think\Log::record('Content-Type: ' . $this->request->header('content-type'), 'debug');
        \think\Log::record('所有POST参数: ' . json_encode($this->request->param(), JSON_UNESCAPED_UNICODE), 'debug');
        \think\Log::record('=== updateServiceNotificationStatus 调试结束 ===', 'debug');
        
        if (empty($subscribeStatus) || !is_array($subscribeStatus)) {
            \think\Log::record('updateServiceNotificationStatus - subscribeStatus is empty or not array: ' . json_encode($subscribeStatus), 'error');
            $this->error('授权状态不能为空或格式错误');
        }
        
        // 处理微信返回的原始格式，将 'accept' 转换为 true，其他转换为 false
        \think\Log::record('=== 开始处理数据格式 ===', 'debug');
        $processedStatus = [];
        foreach ($subscribeStatus as $templateId => $status) {
            \think\Log::record("处理模板 {$templateId}: 原始值 = " . var_export($status, true) . ", 类型 = " . gettype($status), 'debug');
            if ($status === 'accept' || $status === true || $status === '1' || $status === 1) {
                $processedStatus[$templateId] = true;
                \think\Log::record("模板 {$templateId}: 转换为 true", 'debug');
            } else {
                $processedStatus[$templateId] = false;
                \think\Log::record("模板 {$templateId}: 转换为 false", 'debug');
            }
        }
        $subscribeStatus = $processedStatus;
        \think\Log::record('处理后的数据: ' . json_encode($subscribeStatus, JSON_UNESCAPED_UNICODE), 'debug');
        \think\Log::record('=== 数据格式处理完成 ===', 'debug');

        try {
            // 检查表是否存在
            $tableExists = Db::query("SHOW TABLES LIKE 'fa_user_notification_auth'");
            if (empty($tableExists)) {
                // 表不存在，创建表
                $createTableSql = "
                CREATE TABLE `fa_user_notification_auth` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `user_id` int(11) NOT NULL COMMENT '用户ID',
                  `template_id` varchar(50) NOT NULL COMMENT '模板ID',
                  `status` tinyint(1) DEFAULT '0' COMMENT '授权状态：0未授权，1已授权',
                  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
                  `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `uk_user_template` (`user_id`,`template_id`),
                  KEY `idx_user_id` (`user_id`),
                  KEY `idx_template_id` (`template_id`),
                  KEY `idx_status` (`status`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户服务通知授权表';
                ";
                Db::execute($createTableSql);
                error_log('Created table fa_user_notification_auth');
            }
            
            // 保存用户授权状态
            error_log('=== 开始保存到数据库 ===');
            foreach ($subscribeStatus as $templateId => $status) {
                // 确保templateId是字符串
                $templateId = (string)$templateId;
                $status = (bool)$status;
                
                $data = [
                    'user_id' => (int)$userId,
                    'template_id' => $templateId,
                    'status' => $status ? 1 : 0,
                    'updated_at' => date('Y-m-d H:i:s')
                ];
                
                error_log('准备保存数据: ' . json_encode($data, JSON_UNESCAPED_UNICODE));
                
                // 检查是否已存在记录
                $existing = Db::name('user_notification_auth')->where([
                    'user_id' => (int)$userId,
                    'template_id' => $templateId
                ])->find();
                
                if ($existing) {
                    // 更新现有记录
                    $result = Db::name('user_notification_auth')->where([
                        'user_id' => (int)$userId,
                        'template_id' => $templateId
                    ])->update($data);
                    error_log('Updated record for template ' . $templateId . ', result: ' . $result);
                } else {
                    // 插入新记录
                    $data['created_at'] = date('Y-m-d H:i:s');
                    $result = Db::name('user_notification_auth')->insert($data);
                    error_log('Inserted record for template ' . $templateId . ', result: ' . $result);
                }
            }
            
            $this->success('授权状态更新成功');
        } catch (Exception $e) {
            error_log('updateServiceNotificationStatus error: ' . $e->getMessage());
            error_log('updateServiceNotificationStatus error trace: ' . $e->getTraceAsString());
            $this->error('授权状态更新失败：' . $e->getMessage());
        }
    }

    /**
     * 检查新消息
     */
    public function checkNewMessages()
    {
        if (!$this->auth->isLogin()) {
            $this->error('请先登录', null, 401);
        }
        
        $user = $this->auth->getUserinfo();
        $userId = $user['id'];
        $lastCheck = $this->request->get('last_check', 0);
        
        // 获取上次检查时间之后的新消息
        $messages = Db::name('scanwork_message')
            ->where('user_id', $userId)
            ->where('createtime', '>', $lastCheck / 1000) // 转换为秒
            ->order('createtime desc')
            ->select();
            
        foreach ($messages as &$message) {
            $message['createtime_text'] = date('Y-m-d H:i:s', $message['createtime']);
        }
        
        // 获取未读消息数量
        $unreadCount = Db::name('scanwork_message')
            ->where('user_id', $userId)
            ->where('is_read', 0)
            ->count();
        
        $this->success('检查成功', [
            'hasNew' => !empty($messages),
            'messages' => $messages,
            'unreadCount' => $unreadCount
        ]);
    }
    
    /**
     * 将本地文件上传到云端
     */
    protected function uploadToCloud($localPath, $filename)
    {
        try {
            error_log('uploadToCloud - 开始上传到七牛云，本地路径: ' . $localPath);
            
            $date = date('Y/m/d');
            $cloudPath = 'api/uploadImage/' . $date . '/' . $filename;
            
            // 从云存储配置中获取七牛云配置
            $defaultConfig = Db::name('yuncunchu_config')->where('is_default', 1)->where('status', 1)->find();
            if (!$defaultConfig || $defaultConfig['type'] !== 'qiniu') {
                error_log('uploadToQiniu - 未找到七牛云配置或配置类型错误');
                return null;
            }
            
            $qiniuConfig = $defaultConfig['config'];
            if (is_string($qiniuConfig)) {
                $qiniuConfig = json_decode($qiniuConfig, true);
            }
            
            $configData = [
                'access_key' => $qiniuConfig['access_key'] ?? '',
                'secret_key' => $qiniuConfig['secret_key'] ?? '',
                'bucket' => $qiniuConfig['bucket'] ?? '',
                'domain' => $qiniuConfig['domain'] ?? '',
                'zone' => $qiniuConfig['zone'] ?? 'auto'
            ];
            
            return $this->uploadToQiniu($localPath, $cloudPath, $configData);
            
        } catch (Exception $e) {
            error_log('上传到云端失败: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * 上传到本地云存储
     */
    protected function uploadToLocalCloud($localPath, $cloudPath, $configData)
    {
        $uploadDir = $configData['upload_dir'] ?? 'uploads';
        $fullPath = ROOT_PATH . 'public' . DS . $uploadDir . DS . $cloudPath;
        $fullDir = dirname($fullPath);
        
        // 创建目录
        if (!is_dir($fullDir)) {
            mkdir($fullDir, 0755, true);
        }
        
        // 复制文件
        if (copy($localPath, $fullPath)) {
            $url = '/' . $uploadDir . '/' . $cloudPath;
            
            // 保存文件记录到云存储数据库
            try {
                \app\admin\model\yuncunchu\File::create([
                    'config_id' => $configData['id'] ?? 0,
                    'original_name' => basename($localPath),
                    'file_name' => basename($cloudPath),
                    'file_path' => $cloudPath,
                    'file_url' => $url,
                    'file_size' => filesize($localPath),
                    'file_type' => mime_content_type($localPath),
                    'mime_type' => mime_content_type($localPath),
                    'extension' => pathinfo($cloudPath, PATHINFO_EXTENSION),
                    'md5' => md5_file($localPath),
                    'sha1' => sha1_file($localPath),
                    'upload_module' => 'api',
                    'upload_action' => 'uploadImage',
                    'user_id' => $this->auth->isLogin() ? $this->auth->getUserinfo()['id'] : 0,
                    'admin_id' => 0,
                    'status' => 1
                ]);
            } catch (Exception $e) {
                error_log('保存云存储记录失败: ' . $e->getMessage());
            }
            
            return $url;
        }
        
        return null;
    }
    
    /**
     * 上传到阿里云OSS
     */
    protected function uploadToAliyunOSS($localPath, $cloudPath, $configData)
    {
        try {
            error_log('uploadToAliyunOSS - 开始上传到阿里云OSS');
            
            // 检查阿里云OSS配置
            if (empty($configData['access_key_id']) || empty($configData['access_key_secret']) || 
                empty($configData['bucket']) || empty($configData['endpoint'])) {
                error_log('uploadToAliyunOSS - 阿里云OSS配置不完整');
                return null;
            }
            
            // 读取文件内容
            $content = file_get_contents($localPath);
            if ($content === false) {
                error_log('uploadToAliyunOSS - 无法读取文件内容');
                return null;
            }
            
            // 使用阿里云OSS SDK上传
            $ossClient = new \OSS\OssClient(
                $configData['access_key_id'],
                $configData['access_key_secret'],
                $configData['endpoint']
            );
            
            // 上传文件到OSS
            $result = $ossClient->putObject($configData['bucket'], $cloudPath, $content);
            
            // 生成文件URL
            if (isset($configData['domain']) && !empty($configData['domain'])) {
                $fileUrl = rtrim($configData['domain'], '/') . '/' . $cloudPath;
            } else {
                $fileUrl = $result['info']['url'];
            }
            
            error_log('uploadToAliyunOSS - 上传成功，URL: ' . $fileUrl);
            return $fileUrl;
            
        } catch (Exception $e) {
            error_log('uploadToAliyunOSS - 异常: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * 上传到腾讯云COS
     */
    protected function uploadToTencentCOS($localPath, $cloudPath, $configData)
    {
        try {
            error_log('uploadToTencentCOS - 开始上传到腾讯云COS');
            
            // 检查腾讯云COS配置
            if (empty($configData['secret_id']) || empty($configData['secret_key']) || 
                empty($configData['bucket']) || empty($configData['region'])) {
                error_log('uploadToTencentCOS - 腾讯云COS配置不完整');
                return null;
            }
            
            // 读取文件内容
            $content = file_get_contents($localPath);
            if ($content === false) {
                error_log('uploadToTencentCOS - 无法读取文件内容');
                return null;
            }
            
            // 使用腾讯云COS SDK上传
            $cosClient = new \Qcloud\Cos\Client([
                'region' => $configData['region'],
                'credentials' => [
                    'secretId' => $configData['secret_id'],
                    'secretKey' => $configData['secret_key'],
                ]
            ]);
            
            // 上传文件到COS
            $result = $cosClient->putObject([
                'Bucket' => $configData['bucket'],
                'Key' => $cloudPath,
                'Body' => $content
            ]);
            
            // 生成文件URL
            if (isset($configData['domain']) && !empty($configData['domain'])) {
                $fileUrl = rtrim($configData['domain'], '/') . '/' . $cloudPath;
            } else {
                $fileUrl = $result['ObjectURL'];
            }
            
            error_log('uploadToTencentCOS - 上传成功，URL: ' . $fileUrl);
            return $fileUrl;
            
        } catch (Exception $e) {
            error_log('uploadToTencentCOS - 异常: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * 上传到七牛云
     */
    protected function uploadToQiniu($localPath, $cloudPath, $configData)
    {
        try {
            error_log('uploadToQiniu - 开始上传到七牛云');
            
            // 检查七牛云配置
            if (empty($configData['access_key']) || empty($configData['secret_key']) || 
                empty($configData['bucket']) || empty($configData['domain'])) {
                error_log('uploadToQiniu - 七牛云配置不完整');
                return null;
            }
            
            // 生成上传token
            $accessKey = $configData['access_key'];
            $secretKey = $configData['secret_key'];
            $bucket = $configData['bucket'];
            $key = $cloudPath;
            
            // 生成上传策略
            $policy = [
                'scope' => $bucket,
                'deadline' => time() + 3600, // 1小时过期
                'returnBody' => '{"key":"$(key)","hash":"$(etag)","size":"$(fsize)","mimeType":"$(mimeType)"}'
            ];
            
            $policyJson = json_encode($policy);
            $policyBase64 = base64_encode($policyJson);
            $sign = hash_hmac('sha1', $policyBase64, $secretKey, true);
            $token = $accessKey . ':' . base64_encode($sign) . ':' . $policyBase64;
            
            // 准备上传数据
            $postData = [
                'token' => $token,
                'key' => $key,
                'file' => new \CURLFile($localPath)
            ];
            
            // 上传到七牛云
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://up-z2.qiniup.com/');
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
            
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            error_log('uploadToQiniu - 七牛云响应: ' . $response);
            error_log('uploadToQiniu - HTTP状态码: ' . $httpCode);
            
            if ($httpCode == 200) {
                $result = json_decode($response, true);
                if ($result && isset($result['key'])) {
                    $url = $configData['domain'] . '/' . $result['key'];
                    error_log('uploadToQiniu - 上传成功，URL: ' . $url);
                    return $url;
                }
            }
            
            error_log('uploadToQiniu - 上传失败');
            return null;
            
        } catch (Exception $e) {
            error_log('uploadToQiniu - 异常: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * 将本地图片URL转换为云存储URL
     */
    protected function convertLocalImageToCloud($localImageUrl)
    {
        // 如果是云存储URL，直接返回
        if (strpos($localImageUrl, 'https://') === 0 && strpos($localImageUrl, '/uploads/') === false) {
            return $localImageUrl;
        }
        
        // 如果是本地URL，转换为本地文件路径
        if (strpos($localImageUrl, '/uploads/') === 0) {
            $localPath = ROOT_PATH . 'public' . $localImageUrl;
            if (file_exists($localPath)) {
                $filename = basename($localImageUrl);
                $cloudUrl = $this->uploadToCloudStorage($localPath, $filename);
                if ($cloudUrl) {
                    // 小程序无法访问服务器本地文件，返回云存储URL
                    error_log('本地图片已同步到云存储：' . $cloudUrl . '，保持本地备份：' . $localImageUrl);
                    return $cloudUrl; // 返回云存储URL，确保小程序可以访问
                }
            }
        }
        
        // 如果转换失败，返回原URL
        return $localImageUrl;
    }
    
    /**
     * 批量转换本地图片为云存储URL
     */
    protected function convertLocalImagesToCloud($imageUrls)
    {
        if (!is_array($imageUrls)) {
            return $imageUrls;
        }
        
        $cloudUrls = [];
        foreach ($imageUrls as $imageUrl) {
            $cloudUrls[] = $this->convertLocalImageToCloud($imageUrl);
        }
        
        return $cloudUrls;
    }
    
    /**
     * 获取七牛云URL（用于备份访问）
     */
    protected function getQiniuUrl($localImageUrl)
    {
        // 如果是本地URL，转换为七牛云URL
        if (strpos($localImageUrl, '/uploads/') === 0) {
            $domain = 'https://img1.images.023ent.net';
            return $domain . $localImageUrl;
        }
        
        // 如果已经是七牛云URL，直接返回
        if (strpos($localImageUrl, 'https://img1.images.023ent.net') === 0) {
            return $localImageUrl;
        }
        
        // 其他情况返回原URL
        return $localImageUrl;
    }
    
    /**
     * 获取图片的本地和云端URL
     */
    protected function getImageUrls($localImageUrl)
    {
        return [
            'local' => $localImageUrl,
            'cloud' => $this->getQiniuUrl($localImageUrl)
        ];
    }
    
    /**
     * 确认分工
     */
    public function confirmAllocation()
    {
        $allocationId = $this->request->post('allocation_id');
        
        if (!$allocationId) {
            $this->error('缺少分工ID');
        }
        
        // 验证用户身份
        $user = $this->auth->getUserinfo();
        if (!$user) {
            $this->error('用户未登录');
        }
        
        try {
            error_log('confirmAllocation - 开始确认分工，分配ID: ' . $allocationId . ', 用户ID: ' . $user['id']);
            
            // 查找分工记录
            $allocation = Db::name('scanwork_allocation')
                ->where('id', $allocationId)
                ->where('user_id', $user['id'])
                ->find();
            
            error_log('confirmAllocation - 查询结果: ' . json_encode($allocation));
            
            if (!$allocation) {
                error_log('confirmAllocation - 分工记录不存在或不属于当前用户');
                $this->error('分工记录不存在或不属于当前用户');
            }
            
            // 更新分工状态为已确认（状态1表示已完成）
            $updateData = [
                'status' => 1, // 1=已完成
                'updatetime' => time()
            ];
            
            error_log('confirmAllocation - 更新数据: ' . json_encode($updateData));
            
            $result = Db::name('scanwork_allocation')
                ->where('id', $allocationId)
                ->update($updateData);
            
            error_log('confirmAllocation - 更新结果: ' . $result);
            
            if ($result !== false) {
                error_log('confirmAllocation - 分工确认成功，影响行数: ' . $result);
                $this->success('分工确认成功', [
                    'allocation_id' => $allocationId,
                    'status' => 1,
                    'update_time' => time()
                ]);
            } else {
                error_log('confirmAllocation - 分工确认失败，数据库更新返回false');
                $this->error('分工确认失败');
            }
            
        } catch (\Exception $e) {
            error_log('确认分工失败: ' . $e->getMessage());
            error_log('错误文件: ' . $e->getFile());
            error_log('错误行号: ' . $e->getLine());
            error_log('错误堆栈: ' . $e->getTraceAsString());
            $this->error('确认分工时发生错误: ' . $e->getMessage());
        }
    }

    /**
     * 通用云存储上传方法（根据默认配置选择存储提供商）
     */
    protected function uploadToCloudStorage($localPath, $filename)
    {
        try {
            error_log('uploadToCloudStorage - 开始上传到云存储');
            
            // 获取默认云存储配置
            $defaultConfig = Db::name('yuncunchu_config')->where('is_default', 1)->where('status', 1)->find();
            if (!$defaultConfig) {
                error_log('uploadToCloudStorage - 未找到默认云存储配置');
                return null;
            }
            
            $configData = $defaultConfig['config'];
            if (is_string($configData)) {
                $configData = json_decode($configData, true);
            }
            
            // 生成云存储路径
            $date = date('Y-m-d');
            $cloudPath = 'uploads/baogong/' . $date . '/' . $filename;
            
            error_log('uploadToCloudStorage - 使用存储类型: ' . $defaultConfig['type']);
            
            // 根据存储类型选择上传方法
            switch ($defaultConfig['type']) {
                case 'qiniu':
                    return $this->uploadToQiniu($localPath, $cloudPath, $configData);
                case 'aliyun_oss':
                    return $this->uploadToAliyunOSS($localPath, $cloudPath, $configData);
                case 'tencent_cos':
                    return $this->uploadToTencentCOS($localPath, $cloudPath, $configData);
                case 'local':
                    // 本地存储不需要上传，直接返回本地URL
                    $uploadPath = $configData['path'] ?? '/uploads';
                    $uploadUrl = $configData['url'] ?? '/uploads';
                    $localUrl = $uploadUrl . '/baogong/' . $date . '/' . $filename;
                    return ConfigModel::getSiteDomain() . $localUrl;
                default:
                    error_log('uploadToCloudStorage - 不支持的存储类型: ' . $defaultConfig->type);
                    return null;
            }
            
        } catch (Exception $e) {
            error_log('uploadToCloudStorage - 异常: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 简化的七牛云上传方法（带重试机制）
     */
    protected function uploadToQiniuSimple($localPath, $filename)
    {
        $maxRetries = 3; // 最大重试次数
        $retryDelay = 1; // 重试间隔（秒）
        
        for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
            try {
                error_log("uploadToQiniuSimple - 第{$attempt}次尝试上传到七牛云，本地路径: " . $localPath);
                
                // 从数据库获取七牛云配置
                $qiniuConfig = Db::name('yuncunchu_config')->where('type', 'qiniu')->where('status', 1)->find();
                if (!$qiniuConfig) {
                    error_log('uploadToQiniuSimple - 未找到七牛云配置');
                    return null;
                }
                
                $configData = json_decode($qiniuConfig['config'], true);
                if (!$configData) {
                    error_log('uploadToQiniuSimple - 七牛云配置解析失败');
                    return null;
                }
                
                error_log('uploadToQiniuSimple - 使用数据库配置: ' . json_encode($configData));
                
                // 生成云存储路径（保持与本地路径一致）
                $date = date('Y-m-d');
                $cloudPath = 'uploads/baogong/' . $date . '/' . $filename;
                
                // 生成上传token
                $accessKey = $configData['access_key'];
                $secretKey = $configData['secret_key'];
                $bucket = $configData['bucket'];
                $key = $cloudPath;
                
                // 生成上传策略
                $policy = [
                    'scope' => $bucket,
                    'deadline' => time() + 3600, // 1小时过期
                    'returnBody' => '{"key":"$(key)","hash":"$(etag)","size":"$(fsize)","mimeType":"$(mimeType)"}'
                ];
                
                $policyJson = json_encode($policy);
                $policyBase64 = base64_encode($policyJson);
                $sign = hash_hmac('sha1', $policyBase64, $secretKey, true);
                $token = $accessKey . ':' . base64_encode($sign) . ':' . $policyBase64;
                
                // 准备上传数据
                $postData = [
                    'token' => $token,
                    'key' => $key,
                    'file' => new \CURLFile($localPath)
                ];
                
                // 上传到七牛云
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, 'https://up-z2.qiniup.com/');
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                curl_setopt($ch, CURLOPT_TIMEOUT, 30);
                curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时
                
                $response = curl_exec($ch);
                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                $error = curl_error($ch);
                curl_close($ch);
                
                error_log("uploadToQiniuSimple - 第{$attempt}次尝试 - 七牛云响应: " . $response);
                error_log("uploadToQiniuSimple - 第{$attempt}次尝试 - HTTP状态码: " . $httpCode);
                if ($error) {
                    error_log("uploadToQiniuSimple - 第{$attempt}次尝试 - CURL错误: " . $error);
                }
                
                // 添加更详细的调试信息
                error_log("uploadToQiniuSimple - 第{$attempt}次尝试 - 上传参数: " . json_encode([
                    'localPath' => $localPath,
                    'filename' => $filename,
                    'cloudPath' => $cloudPath,
                    'bucket' => $bucket,
                    'domain' => $configData['domain']
                ]));
                
                if ($httpCode == 200) {
                    $result = json_decode($response, true);
                    if ($result && isset($result['key'])) {
                        $url = $configData['domain'] . '/' . $result['key'];
                        error_log("uploadToQiniuSimple - 第{$attempt}次尝试成功，URL: " . $url);
                        return $url;
                    }
                }
                
                // 如果不是最后一次尝试，等待后重试
                if ($attempt < $maxRetries) {
                    error_log("uploadToQiniuSimple - 第{$attempt}次尝试失败，等待{$retryDelay}秒后重试...");
                    sleep($retryDelay);
                    $retryDelay *= 2; // 指数退避
                }
                
            } catch (Exception $e) {
                error_log("uploadToQiniuSimple - 第{$attempt}次尝试异常: " . $e->getMessage());
                if ($attempt < $maxRetries) {
                    sleep($retryDelay);
                    $retryDelay *= 2;
                }
            }
        }
        
        error_log('uploadToQiniuSimple - 所有尝试都失败了');
        return null;
    }

    /**
     * 获取简单工序列表
     */
    public function getSimpleProcessList()
    {
        $processes = Db::name('scanwork_process')
            ->where('status', 1)
            ->field('id, name')
            ->select();
            
        $this->success('获取成功', $processes);
    }

    /**
     * 获取简单员工列表
     */
    public function getSimpleUserList()
    {
        $users = Db::name('user')
            ->field('id, nickname')
            ->select();
            
        $this->success('获取成功', $users);
    }

    /**
     * 获取用户工资数据
     */
    public function getWageData()
    {
        if (!$this->auth->isLogin()) {
            $this->error('未登录', null, 401);
        }
        
        try {
            $workerId = $this->auth->id;
            $month = $this->request->get('month', date('Y-m'));
            
            // 解析月份
            $year = substr($month, 0, 4);
            $monthNum = substr($month, 5, 2);
            
            // 计算月份的开始和结束时间
            $startTime = strtotime("{$year}-{$monthNum}-01 00:00:00");
            $endTime = strtotime("{$year}-{$monthNum}-" . date('t', $startTime) . " 23:59:59");
            
            // 获取计件报工记录
            $pieceReports = Db::name('scanwork_report')
                ->alias('r')
                ->join('scanwork_allocation a', 'r.allocation_id = a.id')
                ->join('scanwork_order o', 'a.order_id = o.id')
                ->join('scanwork_model m', 'a.model_id = m.id')
                ->join('scanwork_process p', 'a.process_id = p.id')
                ->where('r.user_id', $workerId)
                ->where('r.type', 'piece')
                ->where('r.status', 1) // 已审核
                ->where('r.report_time', 'between', [$startTime, $endTime])
                ->field('r.*, o.order_no, m.name as model_name, p.name as process_name, a.price')
                ->select();
            
            // 获取计时报工记录
            $timeReports = Db::name('scanwork_treporttime')
                ->alias('tr')
                ->join('scanwork_tallocationtime ta', 'tr.tallocationtime_id = ta.id')
                ->join('scanwork_order o', 'ta.order_id = o.id')
                ->join('scanwork_model m', 'ta.model_id = m.id')
                ->join('scanwork_process p', 'ta.process_id = p.id')
                ->where('tr.user_id', $workerId)
                ->where('tr.status', 1) // 已审核
                ->where('tr.work_date', 'between', [date('Y-m-d', $startTime), date('Y-m-d', $endTime)])
                ->field('tr.*, o.order_no, m.name as model_name, p.name as process_name')
                ->select();
            
            // 计算工资
            $totalPieceWage = 0;
            $totalTimeWage = 0;
            $totalQuantity = 0;
            $totalHours = 0;
            
            foreach ($pieceReports as &$report) {
                $report['wage'] = $report['quantity'] * $report['price'];
                $totalPieceWage += $report['wage'];
                $totalQuantity += $report['quantity'];
                $report['report_date'] = date('Y-m-d', $report['report_time']);
            }
            
            foreach ($timeReports as &$report) {
                $totalTimeWage += $report['wage'];
                $totalHours += $report['total_hours'];
                $report['report_date'] = $report['work_date'];
            }
            
            $totalWage = $totalPieceWage + $totalTimeWage;
            
            $this->success('获取成功', [
                'month' => $month,
                'piece_reports' => $pieceReports,
                'time_reports' => $timeReports,
                'summary' => [
                    'total_piece_wage' => $totalPieceWage,
                    'total_time_wage' => $totalTimeWage,
                    'total_wage' => $totalWage,
                    'total_quantity' => $totalQuantity,
                    'total_hours' => $totalHours
                ]
            ]);
            
        } catch (\Exception $e) {
            $this->error('获取工资数据失败：' . $e->getMessage());
        }
    }

    /**
     * 提交每日工作报工
     */
    public function submitDailyWorkReport()
    {
        try {
            // 获取原始POST数据
            $rawInput = file_get_contents('php://input');
            \think\Log::info('submitDailyWorkReport - 原始输入数据: ' . $rawInput);
            
            // 尝试解析JSON数据
            $jsonData = json_decode($rawInput, true);
            if ($jsonData) {
                \think\Log::info('submitDailyWorkReport - JSON解析成功: ' . json_encode($jsonData, JSON_UNESCAPED_UNICODE));
                $workDate = isset($jsonData['work_date']) ? $jsonData['work_date'] : '';
                $remark = isset($jsonData['remark']) ? $jsonData['remark'] : '';
                $workItems = isset($jsonData['work_items']) ? $jsonData['work_items'] : [];
            } else {
                // 回退到传统方式
                $workDate = input('post.work_date');
                $remark = input('post.remark', '');
                $workItems = input('post.work_items', []);
            }
            
            // 确保 $workItems 是数组
            if (!is_array($workItems)) {
                \think\Log::warning('submitDailyWorkReport - work_items不是数组，类型: ' . gettype($workItems) . ', 值: ' . var_export($workItems, true));
                $workItems = [];
            }
            
            \think\Log::info('submitDailyWorkReport - 基本参数: work_date=' . $workDate . ', work_items_count=' . count($workItems));
            
            if (!$workDate) {
                return json([
                    'code' => 0,
                    'msg' => '请选择工作日期',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            if (empty($workItems) || !is_array($workItems)) {
                return json([
                    'code' => 0,
                    'msg' => '请至少添加一个工作项目',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            // 验证每个工作项目
            foreach ($workItems as $index => $item) {
                if (!isset($item['order_id']) || !isset($item['model_id']) || !isset($item['process_id'])) {
                    return json([
                        'code' => 0,
                        'msg' => '工作项目' . ($index + 1) . '缺少必要参数',
                        'data' => null,
                        'time' => time()
                    ]);
                }
                
                if (!isset($item['quantity']) || $item['quantity'] <= 0) {
                    return json([
                        'code' => 0,
                        'msg' => '工作项目' . ($index + 1) . '数量必须大于0',
                        'data' => null,
                        'time' => time()
                    ]);
                }
                
                if (!isset($item['work_hours']) || $item['work_hours'] <= 0) {
                    return json([
                        'code' => 0,
                        'msg' => '工作项目' . ($index + 1) . '工作时长必须大于0',
                        'data' => null,
                        'time' => time()
                    ]);
                }
                
                if (!isset($item['work_description']) || trim($item['work_description']) === '') {
                    return json([
                        'code' => 0,
                        'msg' => '工作项目' . ($index + 1) . '请填写工作内容描述',
                        'data' => null,
                        'time' => time()
                    ]);
                }
            }
            
            // 开始事务
            Db::startTrans();
            
            // 创建每日工作报工记录
            $dailyReportData = [
                'user_id' => $this->auth->id ?? 0,
                'work_date' => $workDate,
                'remark' => $remark,
                'status' => 0, // -1: 待质检, 0: 待审核, 1: 通过, 2: 拒绝
                'createtime' => time(),
                'updatetime' => time()
            ];
            
            $dailyReportId = Db::name('scanwork_daily_work_report')->insertGetId($dailyReportData);
            
            \think\Log::info('submitDailyWorkReport - 创建每日工作报工记录成功，ID: ' . $dailyReportId);
            
            // 处理每个工作项目
            foreach ($workItems as $index => $item) {
                // 创建工作项目记录
                $workItemData = [
                    'daily_report_id' => $dailyReportId,
                    'order_id' => $item['order_id'],
                    'model_id' => $item['model_id'],
                    'process_id' => $item['process_id'],
                    'quantity' => $item['quantity'],
                    'work_hours' => $item['work_hours'],
                    'work_description' => $item['work_description'],
                    'createtime' => time(),
                    'updatetime' => time()
                ];
                
                $workItemId = Db::name('scanwork_daily_work_item')->insertGetId($workItemData);
                
                \think\Log::info('submitDailyWorkReport - 创建工作项目记录成功，ID: ' . $workItemId);
                
                // 处理工作图片
                if (isset($item['images']) && is_array($item['images']) && !empty($item['images'])) {
                    foreach ($item['images'] as $imageUrl) {
                        $imageData = [
                            'daily_report_id' => $dailyReportId,
                            'work_item_id' => $workItemId,
                            'image_url' => $imageUrl,
                            'image_type' => 1, // 1: 员工上传的图片
                            'createtime' => time()
                        ];
                        
                        Db::name('scanwork_daily_work_image')->insert($imageData);
                    }
                }
            }
            
            // 提交事务
            Db::commit();
            
            \think\Log::info('submitDailyWorkReport - 提交成功');
            return json([
                'code' => 1,
                'msg' => '每日工作报工提交成功',
                'data' => null,
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            // 回滚事务
            Db::rollback();
            \think\Log::error('submitDailyWorkReport - 提交失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '提交失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取每日工作记录
     */
    public function getDailyWorkRecords()
    {
        try {
            $page = input('get.page', 1);
            $pageSize = input('get.page_size', 10);
            $workDate = input('get.work_date', '');
            $status = input('get.status', '');
            $userId = input('get.user_id', '');
            
            $where = [];
            
            if ($workDate) {
                $where['work_date'] = $workDate;
            }
            
            if ($status !== '') {
                $where['status'] = $status;
            }
            
            if ($userId) {
                $where['user_id'] = $userId;
            }
            
            $offset = ($page - 1) * $pageSize;
            
            // 获取记录列表
            $records = Db::name('scanwork_daily_work_report')
                ->where($where)
                ->order('createtime desc')
                ->limit($offset, $pageSize)
                ->select();
            
            // 处理每条记录
            foreach ($records as &$record) {
                // 获取工作项目统计
                $workItems = Db::name('scanwork_daily_work_item')
                    ->where('daily_report_id', $record['id'])
                    ->select();
                
                $record['work_items_count'] = count($workItems);
                $record['total_quantity'] = array_sum(array_column($workItems, 'quantity'));
                $record['total_work_hours'] = array_sum(array_column($workItems, 'work_hours'));
                
                // 状态文本
                $statusMap = ['0' => '待审核', '1' => '通过', '2' => '拒绝'];
                $record['status_text'] = $statusMap[$record['status']] ?? '未知';
                
                // 格式化时间
                $record['createtime_text'] = date('Y-m-d H:i:s', $record['createtime']);
                
                // 获取用户信息
                if ($record['user_id']) {
                    $user = Db::name('user')->where('id', $record['user_id'])->find();
                    $record['user_name'] = $user ? $user['nickname'] : '未知用户';
                } else {
                    $record['user_name'] = '未知用户';
                }
            }
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => [
                    'list' => $records,
                    'total' => Db::name('scanwork_daily_work_report')->where($where)->count()
                ],
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getDailyWorkRecords - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 获取每日工作统计信息
     */
    public function getDailyWorkStats()
    {
        try {
            $total = Db::name('scanwork_daily_work_report')->count();
            $pending = Db::name('scanwork_daily_work_report')->where('status', 0)->count();
            $approved = Db::name('scanwork_daily_work_report')->where('status', 1)->count();
            $rejected = Db::name('scanwork_daily_work_report')->where('status', 2)->count();
            
            return json([
                'code' => 1,
                'msg' => '获取成功',
                'data' => [
                    'total' => $total,
                    'pending' => $pending,
                    'approved' => $approved,
                    'rejected' => $rejected
                ],
                'time' => time()
            ]);
            
        } catch (Exception $e) {
            \think\Log::error('getDailyWorkStats - 获取失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '获取失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }

    /**
     * 审核每日工作报工
     */
    public function auditDailyWorkReport()
    {
        try {
            $id = input('post.id');
            $status = input('post.status');
            $auditReason = input('post.audit_reason', '');
            
            if (!$id || !in_array($status, [1, 2])) {
                return json([
                    'code' => 0,
                    'msg' => '参数错误',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
            $updateData = [
                'status' => $status,
                'audit_reason' => $auditReason,
                'audit_time' => time(),
                'audit_user_id' => $this->auth->id ?? 0,
                'updatetime' => time()
            ];
            
            $result = Db::name('scanwork_daily_work_report')
                ->where('id', $id)
                ->update($updateData);
            
            if ($result) {
                return json([
                    'code' => 1,
                    'msg' => '审核成功',
                    'data' => null,
                    'time' => time()
                ]);
            } else {
                return json([
                    'code' => 0,
                    'msg' => '审核失败',
                    'data' => null,
                    'time' => time()
                ]);
            }
            
        } catch (Exception $e) {
            \think\Log::error('auditDailyWorkReport - 审核失败: ' . $e->getMessage());
            return json([
                'code' => 0,
                'msg' => '审核失败：' . $e->getMessage(),
                'data' => null,
                'time' => time()
            ]);
        }
    }



    // ==================== HR考勤打卡 ====================
    
    public function clockIn()
    {
        try {
            $userId = $this->auth->isLogin() ? $this->auth->id : input('user_id');
            $longitude = input('longitude');
            $latitude = input('latitude');
            $address = input('address', '');
            $location = input('location', '');
            $image = input('image', '');
            $device = input('device', '');
            
            if (!$userId) {
                return json(['code' => 0, 'msg' => '用户ID不能为空', 'data' => null, 'time' => time()]);
            }
            
            $today = date('Y-m-d');
            $now = time();
            
            $existingRecord = Db::name('hr_attendance')->where('user_id', $userId)->where('attendance_date', $today)->find();
            
            if ($existingRecord && $existingRecord['clock_in_time']) {
                return json(['code' => 0, 'msg' => '今天已经打过上班卡了', 'data' => $existingRecord, 'time' => time()]);
            }
            
            $config = Db::name('hr_attendance_config')->where('is_default', 1)->where('status', 1)->find();
            if (!$config) {
                $config = ['work_start_time' => '09:00', 'late_threshold' => 10];
            }
            
            $workStartTime = strtotime($today . ' ' . $config['work_start_time']);
            $isLate = $now > $workStartTime + ($config['late_threshold'] * 60);
            $lateMinutes = $isLate ? ceil(($now - $workStartTime) / 60) : 0;
            
            $attendanceData = [
                'user_id' => $userId,
                'attendance_date' => $today,
                'clock_in_time' => $now,
                'clock_in_location' => $location,
                'clock_in_address' => $address,
                'clock_in_longitude' => $longitude,
                'clock_in_latitude' => $latitude,
                'clock_in_image' => $image,
                'clock_in_device' => $device,
                'is_late' => $isLate ? 1 : 0,
                'late_minutes' => $lateMinutes,
                'attendance_status' => $isLate ? 2 : 1,
                'createtime' => $now,
                'updatetime' => $now
            ];
            
            if ($existingRecord) {
                Db::name('hr_attendance')->where('id', $existingRecord['id'])->update($attendanceData);
                $attendanceData['id'] = $existingRecord['id'];
            } else {
                $attendanceData['id'] = Db::name('hr_attendance')->insertGetId($attendanceData);
            }
            
            return json(['code' => 1, 'msg' => $isLate ? '打卡成功，您已迟到' : '打卡成功', 'data' => $attendanceData, 'time' => time()]);
            
        } catch (Exception $e) {
            return json(['code' => 0, 'msg' => '打卡失败：' . $e->getMessage(), 'data' => null, 'time' => time()]);
        }
    }
    
    public function clockOut()
    {
        try {
            $userId = $this->auth->isLogin() ? $this->auth->id : input('user_id');
            $longitude = input('longitude');
            $latitude = input('latitude');
            $address = input('address', '');
            $location = input('location', '');
            $image = input('image', '');
            $device = input('device', '');
            
            if (!$userId) {
                return json(['code' => 0, 'msg' => '用户ID不能为空', 'data' => null, 'time' => time()]);
            }
            
            $today = date('Y-m-d');
            $now = time();
            
            $attendanceRecord = Db::name('hr_attendance')->where('user_id', $userId)->where('attendance_date', $today)->find();
            
            if (!$attendanceRecord || !$attendanceRecord['clock_in_time']) {
                return json(['code' => 0, 'msg' => '请先进行上班打卡', 'data' => null, 'time' => time()]);
            }
            
            if ($attendanceRecord['clock_out_time']) {
                return json(['code' => 0, 'msg' => '今天已经打过下班卡了', 'data' => $attendanceRecord, 'time' => time()]);
            }
            
            $config = Db::name('hr_attendance_config')->where('is_default', 1)->where('status', 1)->find();
            if (!$config) {
                $config = ['work_end_time' => '18:00', 'early_leave_threshold' => 10];
            }
            
            $workEndTime = strtotime($today . ' ' . $config['work_end_time']);
            $isEarlyLeave = $now < $workEndTime - ($config['early_leave_threshold'] * 60);
            $earlyLeaveMinutes = $isEarlyLeave ? ceil(($workEndTime - $now) / 60) : 0;
            $workHours = ($now - $attendanceRecord['clock_in_time']) / 3600;
            
            $updateData = [
                'clock_out_time' => $now,
                'clock_out_location' => $location,
                'clock_out_address' => $address,
                'clock_out_longitude' => $longitude,
                'clock_out_latitude' => $latitude,
                'clock_out_image' => $image,
                'clock_out_device' => $device,
                'is_early_leave' => $isEarlyLeave ? 1 : 0,
                'early_leave_minutes' => $earlyLeaveMinutes,
                'work_hours' => round($workHours, 2),
                'updatetime' => $now
            ];
            
            if ($attendanceRecord['is_late'] && $isEarlyLeave) {
                $updateData['attendance_status'] = 3;
            } elseif ($isEarlyLeave) {
                $updateData['attendance_status'] = 3;
            }
            
            Db::name('hr_attendance')->where('id', $attendanceRecord['id'])->update($updateData);
            $attendanceRecord = array_merge($attendanceRecord, $updateData);
            
            return json(['code' => 1, 'msg' => $isEarlyLeave ? '打卡成功，您已早退' : '打卡成功', 'data' => $attendanceRecord, 'time' => time()]);
            
        } catch (Exception $e) {
            return json(['code' => 0, 'msg' => '打卡失败：' . $e->getMessage(), 'data' => null, 'time' => time()]);
        }
    }
    
    public function getTodayAttendance()
    {
        try {
            $userId = $this->auth->isLogin() ? $this->auth->id : input('user_id');
            if (!$userId) {
                return json(['code' => 0, 'msg' => '用户ID不能为空', 'data' => null, 'time' => time()]);
            }
            
            $today = date('Y-m-d');
            $attendance = Db::name('hr_attendance')->where('user_id', $userId)->where('attendance_date', $today)->find();
            $config = Db::name('hr_attendance_config')->where('is_default', 1)->where('status', 1)->find();
            
            return json(['code' => 1, 'msg' => '获取成功', 'data' => ['attendance' => $attendance, 'config' => $config], 'time' => time()]);
            
        } catch (Exception $e) {
            return json(['code' => 0, 'msg' => '获取失败：' . $e->getMessage(), 'data' => null, 'time' => time()]);
        }
    }
    
    public function getAttendanceList()
    {
        try {
            $userId = $this->auth->isLogin() ? $this->auth->id : input('user_id');
            $page = input('page', 1);
            $limit = input('limit', 20);
            $yearMonth = input('year_month', date('Y-m'));
            
            if (!$userId) {
                return json(['code' => 0, 'msg' => '用户ID不能为空', 'data' => null, 'time' => time()]);
            }
            
            $offset = ($page - 1) * $limit;
            
            $list = Db::name('hr_attendance')
                ->where('user_id', $userId)
                ->where('attendance_date', 'like', $yearMonth . '%')
                ->order('attendance_date desc')
                ->limit($offset, $limit)
                ->select();
            
            $total = Db::name('hr_attendance')->where('user_id', $userId)->where('attendance_date', 'like', $yearMonth . '%')->count();
            
            $statusMap = [1 => '正常', 2 => '迟到', 3 => '早退', 4 => '旷工', 5 => '请假', 6 => '加班'];
            foreach ($list as &$item) {
                $item['clock_in_time_text'] = $item['clock_in_time'] ? date('H:i:s', $item['clock_in_time']) : '';
                $item['clock_out_time_text'] = $item['clock_out_time'] ? date('H:i:s', $item['clock_out_time']) : '';
                $item['status_text'] = $statusMap[$item['attendance_status']] ?? '未知';
            }
            
            return json(['code' => 1, 'msg' => '获取成功', 'data' => ['list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit], 'time' => time()]);
            
        } catch (Exception $e) {
            return json(['code' => 0, 'msg' => '获取失败：' . $e->getMessage(), 'data' => null, 'time' => time()]);
        }
    }
    
    public function getAttendanceStatistics()
    {
        try {
            $userId = $this->auth->isLogin() ? $this->auth->id : input('user_id');
            $yearMonth = input('year_month', date('Y-m'));
            
            if (!$userId) {
                return json(['code' => 0, 'msg' => '用户ID不能为空', 'data' => null, 'time' => time()]);
            }
            
            $stats = Db::name('hr_attendance_monthly')->where('user_id', $userId)->where('year_month', $yearMonth)->find();
            
            if (!$stats) {
                $records = Db::name('hr_attendance')->where('user_id', $userId)->where('attendance_date', 'like', $yearMonth . '%')->select();
                
                $stats = [
                    'user_id' => $userId,
                    'year_month' => $yearMonth,
                    'total_days' => 0,
                    'actual_days' => count($records),
                    'normal_days' => 0,
                    'late_days' => 0,
                    'early_leave_days' => 0,
                    'absent_days' => 0,
                    'leave_days' => 0,
                    'overtime_hours' => 0,
                    'total_work_hours' => 0
                ];
                
                foreach ($records as $record) {
                    if ($record['is_late']) $stats['late_days']++;
                    if ($record['is_early_leave']) $stats['early_leave_days']++;
                    if ($record['attendance_status'] == 1) $stats['normal_days']++;
                    $stats['total_work_hours'] += $record['work_hours'];
                    $stats['overtime_hours'] += $record['overtime_hours'];
                }
                
                $stats['createtime'] = time();
                $stats['updatetime'] = time();
                
                $existing = Db::name('hr_attendance_monthly')->where('user_id', $userId)->where('year_month', $yearMonth)->find();
                if ($existing) {
                    Db::name('hr_attendance_monthly')->where('id', $existing['id'])->update($stats);
                    $stats['id'] = $existing['id'];
                } else {
                    $stats['id'] = Db::name('hr_attendance_monthly')->insertGetId($stats);
                }
            }
            
            $attendanceList = Db::name('hr_attendance')->where('user_id', $userId)->where('attendance_date', 'like', $yearMonth . '%')->order('attendance_date desc')->select();
            
            return json(['code' => 1, 'msg' => '获取成功', 'data' => ['stats' => $stats, 'attendance_list' => $attendanceList], 'time' => time()]);
            
        } catch (Exception $e) {
            return json(['code' => 0, 'msg' => '获取失败：' . $e->getMessage(), 'data' => null, 'time' => time()]);
        }
    }

} 